4

可能重复:
缩小图像时如何获得更好的结果

我正在尝试使用下面的代码生成大小为 200 x 200px 的缩略图。它适用于某些图像,但不适用于其他图像。当它不起作用时,会生成具有该大小的缩略图,但只能看到部分图像,而另一部分是灰色的(就像您使用了灰色画笔并涂抹在缩略图上一样)。当它失败时,我无法看到趋势。例如,对于 400 像素 x 400 像素大小的 JPEG 图像,它会失败。如果我尝试生成大小为 150 像素 x 150 像素的缩略图,则不会丢失图像。如果这有帮助,这里是一张导致问题的图像 - 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;
    }

更新:

我做了更多分析,似乎问题在于将缩略图保存到 SQL Server 数据库的 varbinary 列中。我正在使用 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”,以确保不会对大于 8KB 的数据进行静默截断。

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

当然,我返回 abyte[]而不是 a Bitmap,然后将其保存到数据库中。

我真正能看到的唯一区别是Bitmap用高度和宽度实例化我的结果,我没有调用该FillRectangle方法,也没有设置PixelOffsetMode. 我也从Imagea 而不是 aBitmap

希望这对您有所帮助。

于 2012-10-25T16:28:33.723 回答