使用Graphics.DrawImage()缩小某些图像时图像丢失

时间:2012-10-25 16:07:11

标签: c# asp.net

  

可能重复:
  How can I get better results when shrinking an image

我正在尝试使用下面的代码生成大小为200 x 200px的缩略图。它适用于某些图像,但不适用于其他图像。如果它不起作用,缩略图将以该大小生成,但只能看到部分图像而另一部分是灰色的(就像您使用了灰色画笔并涂抹在缩略图顶部)。当它失败时我无法看到趋势。例如,对于400px x 400px大小的JPEG图像,它失败了。如果我尝试生成大小为150px x 150px的缩略图,则不会丢失图像。 如果这有帮助,则会出现一个导致问题的图像 - 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映射。我必须将类型指定为“BinaryBlob”以确保没有数据的静默截断&gt; 8KB。

1 个答案:

答案 0 :(得分: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

开始

希望这可以帮助你。