У меня есть код, который принимает PNG, который представляет собой изображение в оттенках серого с прозрачностью, и пытается создать новое изображение с заданным фоном (смотрится из базы данных) и накладывает оригинал изображение на нем, чтобы создать изображение требуемого цвета с подсветкой и затенением. Код запускается в контексте ASP.NET, но я не думаю, что это имеет значение.Graphics.DrawImage неожиданно изменяет размер изображения
Код отлично работает на моем локальном компьютере, но когда он развертывается на нашем сервере UAT, он дает неожиданные результаты. На UAT создается изображение нужного размера, но затененная/выделенная область, по-видимому, уменьшилась в каждом измерении на 20%. Таким образом, основным изображением, которое я просматриваю, является первоначально 5x29, а выходное изображение - 5x29, а заштрихованная область - 4x23.2 (24-я строка очень немного отличается, но главным образом цвет фона, поэтому я предположил, что делает интерполяцию с изменением размера).
Мой код, который не удается выглядит следующим образом:
private byte[] GetImageData(CacheKey key)
{
byte[] imageData;
using (Image image = Image.FromFile(key.FilePath))
using (Bitmap newImage = new Bitmap(image.Width, image.Height))
{
using (Graphics graphic = Graphics.FromImage(newImage))
{
using (SolidBrush brush = new SolidBrush(ColorTranslator.FromHtml(key.BackgroundColour)))
{
graphic.FillRectangle(brush, 0, 0, image.Width, image.Height);
}
graphic.DrawImage(image, 0, 0);
/*
The following lines see if there is a transparency mask to create final
transparency. It does this using GetPixel and SetPixel and just modifying
the alpha of newImage with the alpha of mask. I don't think this should make a difference but code below anyway.
*/
Bitmap mask;
if (TryGetMask(key.FilePath, out mask))
{
ApplyMask(newImage, mask);
}
using (var memoryStream = new MemoryStream())
{
newImage.Save(memoryStream, ImageFormat.Png);
imageData = memoryStream.ToArray();
}
}
}
return imageData;
}
private void ApplyMask(Bitmap Bitmap, Bitmap mask)
{
if (mask.Width != Bitmap.Width || mask.Height != Bitmap.Height)
{
throw new ArgumentException("Bitmap sizes do not match");
}
for (int y = 0; y < Bitmap.Height; y++)
{
for (int x = 0; x < Bitmap.Width; x++)
{
Color colour = Bitmap.GetPixel(x, y);
colour = Color.FromArgb(mask.GetPixel(x, y).A, colour);
Bitmap.SetPixel(x, y, colour);
}
}
}
Вот изображения я получаю (повторяется четыре раза, чтобы лучше продемонстрировать этот вопрос). Первое - это правильное изображение, которое я получаю с моего локального компьютера. Второе - это то, что появляется у моего сервера UAT, который демонстрирует странную проблему с «уменьшением на 20%». Они используются аналогично тому, как повторяющийся фон, поэтому вы можете понять, почему эффект настолько заметен. Они были сгенерированы на белом фоне, чтобы облегчить эту проблему. У меня есть похожие изображения в других цветах, если кто-то их хочет. :)
В окончательном разъяснении изображения используются, должны быть идентичными (UAT был развернут от того, что я проверил в наше GIT Repro и там никогда не было более одной версии этих изображений, поэтому он не может использовать неправильную версию.
Я думаю, что, возможно, что GDI делает что-то другое на сервере, чем на моем компьютере, но я не могу думать, что это будет или почему.
Любые объяснения этого поведения или еще исправления были бы наиболее ценными. В противном случае мне придется идти и делать все это вручную пиксель за пикселем, делая прозрачность и накладывая себя, что кажется немного глупым.
А, это имеет смысл. Я думал о DPI, но думал, что с использованием того же образа, что это не может быть проблемой. Я не думал, что он может использовать настройку сервера. Спасибо за указатель. И хотя это звучит как правильный ответ, я подожду, чтобы получить код, развернутый в UAT, и протестировать его до фактического тикания. :) – Chris
Отличное решение. Это сводило меня с ума. –
graphic.DrawImage (изображение, x, y, ширина, высота); –