Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I would like:
- to give an image a certain dimetion(320x240)
-to dither to 16 bit color 565
-to reduce colors ( 4 bits per pixel, 16 colors)

the problem:
When I apply the filter on a bmp image(150KB) of (Hexstring 500 KB): dithering and reducing colors with ProcessImageDithering and BitReduction, I try to save the bmp image as image.bmp and I get a very small file of 11 KB(not the desired image of course) which normally must be of about 250KB.
I do not know really which error I have done to get this result

I forget to tell you: 
500KB is the hex string of the image(.bmp) so when I apply dithering and bitreduction I try to convert the bitmap to a hex string(stringToTest) and this string paste in a text document in a form (0x45, 0x55 ....) and must have less than 500KB (ex: 250KB) and with this file I could with another program try to build the image to examin it


What I have tried:

private Bitmap ProcessImageDithering(BitmapImage sourceImage)
        {
            var result = new System.Drawing.Bitmap((int)sourceImage.Width, (int)sourceImage.Height, System.Drawing.Imaging.PixelFormat.Format16bppRgb565);
            
            return result;
        }

private FormatConvertedBitmap BitReduction(ImageSource myBitmapImageFit)
        {
            FormatConvertedBitmap fcb = new FormatConvertedBitmap();
            fcb.BeginInit();
            fcb.Source = myBitmapImageFit as BitmapSource;
            fcb.DestinationFormat = System.Windows.Media.PixelFormats.Indexed4;
            fcb.DestinationPalette = BitmapPalettes.Halftone8;
            fcb.EndInit();
            return fcb;
        }

private void ApplyFilter(string path)
        {
             BootScreen = BootScreenColored;//property of ImageSource
           
            BitmapImage myBitmapImage = new BitmapImage();

            // BitmapSource objects like BitmapImage can only have their properties
            // changed within a BeginInit/EndInit block.
            myBitmapImage.BeginInit();
            if (path == String.Empty)
            {
                //myBitmapImage.StreamSource = new 
                 MemoryStream(this.SelectedFile.BootScreen);//boorscreen is byte[] which contains data of the image
                myBitmapImage.StreamSource = new MemoryStream(ImageSourceToBytes(new BmpBitmapEncoder(), BootScreenColored)); //PngBitmapEncoder
            }
            else
            {
                myBitmapImage.UriSource = new Uri(path);
            }
            myBitmapImage.DecodePixelHeight = (int)HEIGHT;//240
            myBitmapImage.DecodePixelWidth = (int)WIDTH;//320
            myBitmapImage.EndInit();

           

            
            
            
            var result = ProcessImageDithering(myBitmapImage);//Applying  dithering 
                                                              
            //Reduce colors 4 bits per pixel or 16 colors
            var bitmapImage = BitReduction(myBitmapImage);
            //BitmapImage2Bitmap(ByteToBitmapImage(bitmapBytes)).Save(@"C:\_DataFiles\image.bmp");
            var newBitmap = BitmapImage2Bitmap(bitmapImage.Source as BitmapImage);
            byte[] newbytes = BitmapToBytes(newBitmap);
           
            string StringToTest = BitConverter.ToString(newbytes);
        }
Posted
Updated 27-Sep-19 1:17am
v2

Quote:
I do not know really which error I have done to get this result.

First error is that you have wrong expectations.
An uncompressed bitmap image of dimension 320*240 and 16 bits per pixel got a size of 320*240*2 bytes + headers, which is a bout 320*240*2= 153600 bytes + headers.
With 4 bits per pixel, it is 320*240*0.5= 38400 + headers.
Size is divided by 4 without dimension change.
So, expecting 250KB from 500KB imply other values or dimension increase.
Quote:
I get a very small file of 11 KB

Note that a bmp can be compressed too.
BMP file format - Wikipedia[^]

You also forgot to tell what characteristics are the 500KB image.

[Update]
Quote:
I forget to tell you: 500KB is the hex string of the image(.bmp) so when I apply dithering and bitreduction I try to convert the bitmap to a hex string(stringToTest) and this string pasted in a text document in a form (0x45, 0x55 ....) must have less than 500KB (ex: 250KB) and with this file I could with another program try to build the image to examin it

In France we have a colorful saying which fit what you did: "Why make things simple when you can make them complicated ?"
Reducing an image is not a UI thing.
Procedure: Input parameter: file name and path, Output parameter: file name and path
- Read image to byte array.
- Apply dithering and reducing colors algorithm to another byte array.
- Write resulting file.
 
Share this answer
 
v2
Comments
abdel hayan 30-Jul-19 1:40am    
Which characteristics do you mean?
abdel hayan 30-Jul-19 1:41am    
do you have any suggestions?
abdel hayan 30-Jul-19 2:01am    
I forget to tell you: 500KB is the hex string of the image(.bmp) so when I apply dithering and bitreduction I try to convert the bitmap to a hex string(stringToTest) and this string pasted in a text document in a form (0x45, 0x55 ....) must have less than 500KB (ex: 250KB) and with this file I could with another program try to build the image to examin it
Patrice T 30-Jul-19 6:44am    
Use Improve question to update your question.
So that everyone can pay attention to this information.
abdel hayan 30-Jul-19 8:25am    
I will it now update
Thanks
Finally I tried this and it works:
Cloning the bitmap to the right format

Public void ApplyFilter(string path){
Bitmap myImageResult = BitmapImage2Bitmap(path);

//Dither to 16 bits per pixel colors 565
Bitmap DitherTo16Colors = myImageResult.Clone(new Rectangle(0, 0, myBitmapImage.DecodePixelWidth, myBitmapImage.DecodePixelHeight), System.Drawing.Imaging.PixelFormat.Format16bppRgb565);

//Reduce colors (4 bits per pixel, 16 colors)
Bitmap ReduceTo4bitsPerPixel = DitherTo16Colors.Clone(new Rectangle(0, 0, myBitmapImage.DecodePixelWidth, myBitmapImage.DecodePixelHeight), System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
}
 
Share this answer
 
Start by doing "whatever" just a "little bit" and observe the changes. When the results start to deteriorate, adjust the variables accordingly.

If you get lousy results right from the start, then rethink your whole approach.
 
Share this answer
 
Comments
abdel hayan 7-Aug-19 7:42am    
Do you have any suggestions or procedure to follow?
abdel hayan 16-Sep-19 5:28am    
Thank you Patrice T and Gerry Schmitz
Here is the best way to reduce colors of an image to 16 colors (4bit indexed).
using Magick.NET-Q16-AnyCPU which can be downloaded in visual studio by nuget package manager:
private Bitmap MagickReduction(Bitmap bmp)
        {
            Bitmap imageResult = new Bitmap(bmp.Width,bmp.Height);
            using (MagickImage image = new MagickImage(bmp))
            {
                image.ColorType = ColorType.Palette;// set the color type of image
                
                //dithering and number of required colors
                QuantizeSettings settings = new QuantizeSettings
                {
                    DitherMethod = DitherMethod.FloydSteinberg,
                    Colors = 16,
                };
                image.Quantize(settings);
                image.Normalize();//increase contrast 
                imageResult = image.ToBitmap(ImageFormat.Bmp);
            }
            return imageResult;
        }

in the settings you have to choose how many colors do you want to use in the palette and Quantize methode do the magic work for you
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900