4

重複の可能性:
画像を縮小するときに、より良い結果を得るにはどうすればよいですか

以下のコードを使用して、サイズ 200 x 200px のサムネイルを生成しようとしています。特定の画像では正常に機能しますが、他の画像では機能しません。機能しない場合、サムネイルはそのサイズで生成されますが、部分的な画像のみが表示され、他の部分は灰色になります (灰色のブラシを使用してサムネイルの上に塗ったように)。失敗したときの傾向が見えていません。たとえば、サイズが 400px x 400px の JPEG 画像では失敗します。サイズが 150px x 150px のサムネイルを生成しようとしても、画像が失われることはありません。これが役立つ場合、問題を引き起こす画像が 1 つあります - http://s11.postimage.org/sse5zhpqr/Drawing_8.jpg

あなたの時間を大切にしてください。

    public Bitmap GenerateThumbnail(Bitmap sourceBitmap, int thumbnailWidth, int thumbnailHeight)
    {
        Bitmap thumbnailBitmap = null;

        decimal ratio;
        int newWidth = 0;
        int newHeight = 0;

        // If the image is smaller than the requested thumbnail size just return it
        if (sourceBitmap.Width < thumbnailWidth &&
            sourceBitmap.Height < thumbnailHeight)
        {
            newWidth = sourceBitmap.Width;
            newHeight = sourceBitmap.Height; 
        }
        else if (sourceBitmap.Width > sourceBitmap.Height)
        {
            ratio = (decimal)thumbnailWidth / sourceBitmap.Width;
            newWidth = thumbnailWidth;
            decimal tempDecimalHeight = sourceBitmap.Height * ratio;
            newHeight = (int)tempDecimalHeight;
        }
        else
        {
            ratio = (decimal)thumbnailHeight / sourceBitmap.Height;
            newHeight = thumbnailHeight;
            decimal tempDecimalHeight = sourceBitmap.Width * ratio;
            newWidth = (int)tempDecimalHeight;
        }

        thumbnailBitmap = new Bitmap(newWidth, newHeight);

        Graphics g = Graphics.FromImage(thumbnailBitmap);
        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

        g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
        g.DrawImage(sourceBitmap, 0, 0, newWidth, newHeight);
        g.Dispose();


        return thumbnailBitmap;
    }

アップデート:

さらに分析を行ったところ、サムネイルを varbinary 列の SQL Server データベースに保存しているときに問題が発生したようです。以下のように、MemoryStream を使用してそれを実行しています。ディスクに保存すると、問題なく表示されます。これがデータベースからの私のサムネイルです - http://s12.postimage.org/a7j50vr8d/Generated_Thumbnail.jpg

 using (MemoryStream thumbnailStream = new MemoryStream())
{             
          thumbnailBitmap.Save(thumbnailStream, System.Drawing.Imaging.ImageFormat.Jpeg);               
          return thumbnailStream.ToArray();

}

更新 - この問題は解決されました。問題は、varbinary 列に使用していた NHibernate マッピングでした。8KB を超えるデータがサイレントに切り捨てられないように、型を「BinaryBlob」として指定する必要がありました。

4

1 に答える 1

2

ありがたいことに、これはおそらくコメントであり、回答ではありませんが、追加のフォーマットについては、回答として投稿しています。

画像を縮小するために使用したコードは次のとおりですが、この問題が発生したことはありません。

private byte[] ResizeImage(System.Drawing.Image image, double scaleFactor)
        {
            //a holder for the result
            int newWidth = (int)(image.Width * scaleFactor);
            int newHeight = (int)(image.Height * scaleFactor);

            Bitmap result = new Bitmap(newWidth, newHeight);

            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(image, 0, 0, result.Width, result.Height);
            }

            //return the resulting bitmap
            ImageConverter converter = new ImageConverter();
            return (byte[])converter.ConvertTo(result, typeof(byte[]));            
        }

確かに、データベースに保存するときに、を返すのbyte[]ではなく、を返します。Bitmap

私が実際に見ることができる唯一の違いはBitmap、高さと幅で結果をインスタンス化すること、FillRectangleメソッドを呼び出さないこと、そしてを設定しないことPixelOffsetModeです。私もImage代わりにBitmap

これがどういうわけかあなたを助けることを願っています。

于 2012-10-25T16:28:33.723 に答える