Graphics.DrawImage niespodziewanie zmienia rozmiar obrazu

Mam kod, który przyjmuje png, który jest obrazem w skali szarości z przezroczystością i próbuje utworzyć nowy obraz, który ma dany kolor tła (wyszukany z bazy danych) i nakłada na niego oryginalny obraz, aby utworzyć obraz wymagany kolor z podświetleniem i cieniowaniem. Kod jest uruchamiany w kontekście ASP.NET, ale nie sądzę, że jest to istotne.

Kod działa dobrze na moim komputerze lokalnym, ale po wdrożeniu na naszym serwerze UAT daje nieoczekiwane wyniki. Na UAT tworzy obraz o odpowiednim rozmiarze, ale zacieniony / podświetlony obszar wydaje się być skurczony w każdym wymiarze o 20%. Główny obraz, na który patrzę, to początkowo 5x29, a obraz wyjściowy to 5x29, ale zacieniony obszar to 4x23.2 (24 wiersz jest nieco inny, ale głównie kolor tła, więc założyłem, że robi pewną interpolację ze zmianą rozmiaru) ).

Mój kod, który nie działa, wygląda następująco:

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);
        }
    }
}

Oto obrazy, które otrzymuję (powtarzane cztery razy, aby lepiej pokazać problem). Pierwszy to poprawny obraz, jaki otrzymuję z mojego lokalnego komputera. Drugim jest to, co pojawia się na moim serwerze UAT, który wykazuje dziwny problem „obniżony o 20%”. Są one używane w podobny sposób jak powtarzające się tło, dzięki czemu można zobaczyć, dlaczego efekt jest tak zauważalny. Zostały one wygenerowane na białym tle, aby ułatwić sprawdzenie problemu. Mam podobne obrazy w innych kolorach, jeśli ktoś ich chce. :)

Jako ostateczne wyjaśnienie używane obrazy powinny być identyczne (UAT został wdrożony z tego, co sprawdziłem w naszym reprocesie GIT, i nigdy nie było więcej niż jednej wersji tych obrazów, więc nie może używać niewłaściwej wersji).

Myślę, że może bazowy interfejs GDI robi coś innego na serwerze niż na moim komputerze, ale nie mogę myśleć, co by to było lub dlaczego.

Wszelkie wyjaśnienia dotyczące tego zachowania lub jeszcze lepszych poprawek byłyby najbardziej doceniane. W przeciwnym razie będę musiał zrobić to wszystko ręcznie, piksel po pikselu, wykonując przezroczystość i nakładając się, co wydaje się trochę głupie.

questionAnswers(3)

yourAnswerToTheQuestion