how can a 512x512 bmp image have 1MB of size

2.8k Views Asked by At

my code to save bmp format:

ImgResult.Save(dlgSavePicture.FileName, System.Drawing.Imaging.ImageFormat.Bmp)

I have tried the code and the output is a 512x512 bmp image with 1 megabyte size

if i use ms paint to create a 515x512 bmp image, the size is 768kb

i have tried to open the image and resave as bmp and the size still 1MB

can a 512x512 bmp image size upto 1mb in 512x512? or there are something wrong with my code?

2

There are 2 best solutions below

0
On

i have tried this code

Public Function ConvertTo24bpp(img As Image) As Bitmap
    Dim bmp = New Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    Using gr = Graphics.FromImage(bmp)
        gr.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height))
    End Using
    Return bmp
End Function

ImgResult = New Bitmap(Original)
        For j = 0 To Original.Height - 1
            For i = 0 To Original.Width - 1
                ImgResult.SetPixel(i, j, Color.FromArgb(resultArray2(j, i, 0), originalArray(j, i, 1), resultArray2(j, i, 2)))
            Next
        Next

Dim clone As Bitmap
            clone = ConvertTo24bpp(ImgResult)
            clone.Save(dlgSavePicture.FileName)

the output is 24bit 512x512 bmp image but it size is ~640 KB not ~678 KB

i think the output is png format with bmp extension

is my code gone wrong?

0
On

BMP is a very simple image file format. Just a little header that describes the image (size, pixel format, resolution, color table), followed by a blob of pixel data. Technically it can be compressed with RLE but encoders don't bother anymore. The pixel data depends on the pixel format, ancient ones are 1bpp, 4bpp and 8bpp, they require a color table. 16bpp can happen, unusual, normal ones are 24bpp (RGB) and 32bpp (ARGB). In other words, 3 or 4 bytes per pixel.

So yes, 512 x 512 x 4 ~= 1 megabyte. MSPaint is pretty explicit about the pixel format it uses. It is a very simple painting program without support for alpha blending effects. So uses 24bpp (no alpha), 512 x 512 x 3 ~= 786 kilobytes. You could use Paint.NET to create 32bpp BMPs.

Which one you get in your own program depends on how you created the Bitmap object. The simple version uses the same pixel format as the video adapter. On all modern machines that's 32bpp. 16bpp can happen, it is very unusual. If you want another format then you have to use the Bitmap constructor that takes a PixelFormat argument.

There's otherwise a pretty good reason to do this, the default pixel format is not usually the most optimal one. The best one by a factor of 10 is the format that matches the pixel format of the video adapter exactly. Choice is between 32bppArgb and 32bppPArgb. The P means "pre-multiplied", the alpha value is applied to the RGB values up front. Argb is most efficient if you do a lot of drawing into the bitmap yourself with Graphics.FromImage(). PArgb is most efficient for painting, the pixel data can be blitted to the video frame buffer directly without having to be converted. Ten times faster. You usually care about painting speed, the most visible artifact of a program.

If you care about image file size then there is no better choice than PNG. It compresses the pixel data with LZW compression, typical compression rates are 50% or better. JPEG is a decent choice as well, much higher compression rates, but it is lossy. It achieves high rates by throwing away image details. Suitable for photos, in general images without text or line art, that don't otherwise have to be compressed multiple times.