8

透明度のあるグレースケール画像である png を取得し、特定の背景色 (データベースから検索) を持つ新しい画像を作成しようとし、その上に元の画像を重ねて画像を作成するコードをいくつか持っています。ハイライトとシェーディングで必要な色。コードは ASP.NET コンテキストで実行されますが、それは関係ないと思います。

コードはローカル コンピューターでは問題なく動作しますが、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);
        }
    }
}

これが私が得ている画像です(問題をよりよく示すために4回繰り返しました)。1 つ目は、ローカル コンピューターから取得した正しい画像です。2 つ目は、奇妙な「20% 減少」の問題を示している私の UAT サーバーから得られるものです。これと同様の方法で繰り返し背景として使用されているため、効果が非常に顕著である理由がわかります。これらは、問題を簡単に確認できるように、白い背景で生成されました。誰かがそれらを望むなら、私は他の色の同様の画像を持っています. :)

ここに画像の説明を入力ここに画像の説明を入力ここに画像の説明を入力ここに画像の説明を入力

ここに画像の説明を入力ここに画像の説明を入力ここに画像の説明を入力ここに画像の説明を入力

最終的な明確化として、使用されているイメージは同一である必要があります (UAT は、GIT 再現にチェックインしたものから展開されたものであり、これらのイメージの複数のバージョンが存在したことはないため、間違ったバージョンを使用することはできません。

基になる GDI がサーバー上とコンピューター上で何か違うことをしている可能性があると考えていますが、それが何であるか、またはその理由はわかりません。

この動作についての説明、またはさらに良い修正をいただければ幸いです。それ以外の場合は、ピクセルごとに手動で透明度とオーバーレイを自分で行う必要がありますが、これは少しばかげているようです。

4

3 に答える 3

2

たぶん、graphics.DpiXgraphics.DpiYに問題があり、両方のプロパティがコンピューターとサーバーで同じ値を持っているかどうかを確認します

于 2013-08-07T12:39:45.047 に答える