How to reduce the size of an image in C# and .NET 3.5?

后端 未结 7 1482
忘掉有多难
忘掉有多难 2020-12-05 16:10

I have a screen shot I take in my mobile app. The screen shot takes about 32 KB when saved as a png on a disk.

I am sending these to a central SQL Server and 32 KB

相关标签:
7条回答
  • 2020-12-05 16:37

    Firing up Fireworks with a photo, which won't be the same but should give an idea

    66% quality JPG with no smoothing is 17.5k
    PNG8 with 256 colours is 58K (down to 42 using websnap palette)
    PNG8 with black and white palette is 14k
    

    Note that many image files will be smaller with a screen shot since there are large contiguous groupings of the same colour, and that may be especially true with black and white. It will probably also depend on the algorithm used to convert the image, but you may want to just go with whatever you can find...

    0 讨论(0)
  • 2020-12-05 16:46

    Try converting to a pure monochrome bitmap. These are extremely small, since they only use one bit per pixel.

    EDIT: I'm a liar. Just tried this in Paint and it's about 40k compared to the original 20k. I could have sworn those had massive space savings when I used them before...

    EDIT EDIT: OK, apparently they do have massive savings. It's just that for these images, PNG has even more massive savings. Just tried a 16-color bitmap instead and that blew it up to 150k.

    EDIT EDIT EDIT: BUT, the monochrome bitmap zips to 9k bytes, while the PNG stays at 20k even zipped.


    So, it looks like if you want to go the compression route, you can first convert to monochrome bitmap, then compress for images around half the size of the PNG.

    You could also strip some of the information out of the image. For instance, on that screen, the only thing that really needs to remain an image is the signature. The bars above and below that could be ripped out, and the numeric information could be sent as such and stored separately.

    0 讨论(0)
  • 2020-12-05 16:47

    If monochrome image is acceptable, you can try TIFF G4 (lossless compression). TIFF G4 is known for being very effective in file size to store black and white image. Unfortunately I dont have any info available on how it compares to PNG, but worth investigating into it.

    Here is the info and example on how to do it in C#

    0 讨论(0)
  • 2020-12-05 16:48

    FWIW storing the image physically inside SQL server isn't an optimal solution. If you're using Sql Server 2008 you should look at the file stream support that will let you store the physical images on disk and access them as if they were internal to SQL Server. This would most likely alleviate your need to worry about filesize.

    0 讨论(0)
  • 2020-12-05 16:50
        private static Image ResizeImage(int newSize, Image originalImage)
        {
            if (originalImage.Width <= newSize)
                newSize = originalImage.Width;
    
            var newHeight = originalImage.Height * newSize / originalImage.Width;
    
            if (newHeight > newSize)
            {
                // Resize with height instead
                newSize = originalImage.Width * newSize / originalImage.Height;
                newHeight = newSize;
            }
    
            return originalImage.GetThumbnailImage(newSize, newHeight, null, IntPtr.Zero);
        }
    

    This should work with your Bitmap object Type and resize the Height or Width, depending on which is appropriate for your image dimensions. It will also maintain scale.

    EDIT:

    You could create a new Bitmap object and resize your original image into that Bitmap object.

    Bitmap b = new Bitmap(newWidth, newHeight);
    Graphics g = Graphics.FromImage((Image)b);
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    
    g.DrawImage(imgToResize, 0, 0, newWidth, newHeight);
    g.Dispose();
    
    return (Image)b;
    

    I don't have the Compact Framework installed, but it seems that this should work for you.

    0 讨论(0)
  • 2020-12-05 16:59

    Change the color palette to a lower color depth. Take a look at this question (well look at the answert really) which shows converting to 1bpp. You could go to 8bpp instead of 1bpp and have significant size savings. The mechanism for conversion will be the same as what is shown.

    EDIT

    Thinking out of the box, you might also consider just sending the data points from the upper part of the screen and the signature vector, and have the server recreate the screen for you. If size really is a big issue, I'd probably investigate that.

    EDIT 2

    If simply resizing the image is a reasonable solution (you'll obviously lose data in doing so) then you can use the Imaging namespace in the SDF to create a thumbnail as Alex explains here.

    0 讨论(0)
提交回复
热议问题