开发者

C#: Preserving Bits per Plane when resizing images

I'm developing a service in which users can upload images and save them in a library. I want to preserve the original file (so people can upload high resolution images), but also make a copy of the image to use as a thumbnail.

The problem I have is that the thumbnail "weights" much more than the original file, proportionally. When I check the basic properties of each file (in XnView), I can see that the original files are for instance saved with 32 bits per Plane, whereas the source file will have, for instance, only 24 bits per plane.

What would be the correct way to make a copy of the original file while still using compression? This is an excerpt of the code:

private void ResizeImage(string originalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider, string directory)
    {
        System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(originalFile);

        // Prevent using images internal thumbnail
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);
        FullsizeImage.RotateFlip(System.Drawing.RotateFlipType.Rotate180FlipNone);

        if (OnlyResizeIfWider)
        {
            if (FullsizeImage.Width <= NewWidth)
            {
                NewWidth = FullsizeImage.Width;
            }
        }

        int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width;
        if (NewHeight > MaxHeight)
        {
            // Resize with height instead
            NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;
            NewHeight = MaxHeight;
        }

        System.Drawing.Image NewImage = FullsizeImage.GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);

        // Clear handle to original file so that we can overwrite it if necessary
        Full开发者_运维技巧sizeImage.Dispose();

        // Save resized picture
        NewImage.Save(directory + Path.DirectorySeparatorChar + NewFile);
    }


I would suggest you save the image as a PNG or JPEG stream. That will be much more efficient. Considering that the thumbnail is not the original data, it is probably OK to apply strong compression on it (QF < 60). I once managed to get useful JPEG images in less than 1000 bytes. At that point, they're so small you can consider putting them in a database rather than on disk.

EDIT: (after reading the question fully :) )

And to answer the question, the result of GetThumbnailForImage(), is again an Image so you can call the Save method on it, one of the overloads allows you to specify which compression to use.


Rather than calling GetThumbnailImage, you can create a new image of the size you want and the PixelFormat that you want, and then scale the original image into that.

System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(originalFile);

// Create a bitmap that's NewWidth x NewHeight
Bitmap bmp = new Bitmap(NewWidth, NewHeight, PixelFormat.Format24bppRgb);

// Get a Graphics object for that image and draw the original image into it
using (Graphics g = Graphics.FromImage(bmp))
{
    g.DrawImage(FullsizeImage, 0, 0, NewWidth, NewHeight);
}

// you now have a 24bpp thumbnail image
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜