Reduce color depth and color palette Processing

Source: Internet
Author: User
Tags 0xc0 bmp image

I talked about the BMP bitmap format and image processing. Let's do something else. Okay, let's continue. The data in BMP format is stored in the memory, and you can leave it alone.
In a word, let's figure out its structure and use your clear logic to process it.
what we need to do this time is to reduce the color depth and color palette processing. I did not find anything similar to C ++ or anything else in the garden. In short, we need to use the color palette for both of the two tasks.
to obtain all the colors of an image palette, image. palette. entries, you can get a color array. Some images with fixed color depth have default color palette, such as four (16 colors), eight (256 colors), and so on. You must have seen images of pig liver when you have used win31 or Win95 without a video card driver. We initialize a 4-digit BMP image (16 colors) to see which colors are available in its default palette, add a button named "color sample". This is his Code :

// Display the default Windows color sample void makecolor () {bitmap BMP = new Bitmap (1, 1, pixelformat. format4bppindexed); color [] colors = BMP. palette. entries; graphics gph = graphics. fromhwnd (this. handle); Int J = 0; For (INT I = 0; I <4; I ++) {for (int K = 0; k <4; k ++) {gph. fillrectangle (New solidbrush (colors [J]), new rectangle (new point (K * 100, I * 100), new size (100,100); gph. drawstring (colors [J]. toargb (). tostring ("X "). substring (2), new font (New fontfamily (""), 15), brushes. lavender, new point (K * 100, I * 100); j ++ ;}} BMP. dispose ();}

 
The color table is available (the color table captured in the code above ), then how to make the color of each pixel match the latest color according to the color palette? http://dev.gameres.com/Program/Visual/Other/256color.htm this is a C ++ implementation, but I did not understand --! Using another dummies to add a palette named"AlgorithmThis is his code:

// 256 color palette matching processing http://dev.gameres.com/Program/Visual/Other/256color.htm // didn't understand but I implemented his other very inefficient algorithm // palette matching/reduced color depth algorithm a little less efficient principle is correct // The result is exactly the same as that of the image board saved as 16 colors. 256 colors are the same as void tranto16 () {bitmap IMG = (Bitmap) bitmap. fromfile ("mm.bmp"); // prepare the color palette. This is the color [] colors = new color [16] captured in the new 16-color bitmap file. colors [0] = color. fromargb (0x00, 0x00, 0x00); colors [1] = color. fromargb (0x80, 0x00, 0x00); colors [2] = color. fromargb (0x00, 0x80, 0x00); colors [3] = color. fromargb (0x80, 0x80, 0x00); colors [4] = color. fromargb (0x00, 0x00, 0x80); colors [5] = color. fromargb (0x80, 0x00, 0x80); colors [6] = color. fromargb (0x00, 0x80, 0x80); colors [7] = color. fromargb (0x80, 0x80, 0x80); colors [8] = color. fromargb (0xc0, 0xc0, 0xc0); colors [9] = color. fromargb (0xff, 0x00, 0x00); colors [10] = color. fromargb (0x00, 0xff, 0x00); colors [11] = color. fromargb (0xff, 0xff, 0x00); colors [12] = color. fromargb (0x00, 0x00, 0xff); colors [13] = color. fromargb (0xff, 0x00, 0xff); colors [14] = color. fromargb (0x00, 0xff, 0xff); colors [15] = color. fromargb (0xff, 0xff, 0xff); graphics gph = graphics. fromhwnd (this. handle); int TMP; For (INT I = 0; I 

How can I try it? Use a 16-color bitmap to see if it is exactly the same as him. This shows that our method is correct. The image is really terrible.

Sometimes Win95 is amazing.ProgramThey can use the 4-digit mode to display images that are not too bad (the jitter algorithm is not enough)
Is there a way to retain the image quality and reduce the amount of data. If you want to change the color palette, make sure that the color of the palette matches the image as much as possible. As mentioned above, obtaining the color palette and the color in the palette are very simple. palette does not work by assigning values to the color of the palette or directly changing the color palette. If any of you knows, let me know. Refer to the first example in the previous article. We know that we have to perform operations on the BMP memory data directly by means of the format. This article only discusses the method and will not write the code for the palette operation here, you can use a piece of lazy code to witness his feasibility. Change the 16 rows assigned to the colors array as follows:

 
Random RDM = new random (); For (INT I = 0; I <colors. length; I ++) colors [I] = IMG. getpixel (RDM. next (0, IMG. width-1), RDM. next (0, IMG. height-1 ));

 

Does this image look like a 16-color image? No, it looks much better than a 16-color image. How about the magic of the color palette? The image quality is greatly improved. You can write better algorithms to analyze the color of the image to generate a more intelligent color palette. In the old game, the color palette is widely used due to the limited number of hair colors.

At the end of this article, we will actually write an example of converting 24-bit real-color BMP images to 8-bit 256 colors. Add a button called "reduce color depth", which is the corresponding code:

Void tranto256 () {bitmap srcimg = new Bitmap ("mm.bmp"); bitmap desimg = new Bitmap (srcimg. width, srcimg. height, pixelformat. format8bppindexed); memorystream desimgdata = new memorystream (); desimg. save (desimgdata, imageformat. BMP); color [] pal = desimg. palette. entries; bitmapdata DATA = srcimg. lockbits (New rectangle (0, 0, srcimg. width, srcimg. height), imagelockmode. readwrite, srcimg. pixelformat); unsafe {byte * PTR = (byte *) data. scan0; int TMP; // scan from top to bottom, and store from bottom to top (INT I = 0; I <srcimg. height; I ++) // (INT I = srcimg. height-1; I> 0; I --) {int offset = data. stride * I; for (Int J = 0; j <srcimg. width * 3; j + = 3) {TMP = 255*3; byte palindx = 0; For (int K = 0; k <pal. length; k ++) {color src = pal [k]; color des = color. fromargb (PTR [Offset + J + 2], PTR [Offset + J + 1], PTR [Offset + J]); int val = math. ABS (DES. r-Src. r) + math. ABS (DES. g-Src. g) + math. ABS (DES. b-Src. b); If (Val <TMP) {TMP = val; palindx = (byte) K ;}} desimgdata. writebyte (palindx) ;}} desimg = (Bitmap) bitmap. fromstream (desimgdata); srcimg. unlockbits (data); graphics. fromhwnd (this. handle ). drawimage (desimg, new point (0, 0); desimg. save ("gs.bmp"); desimgdata. close (); srcimg. dispose (); desimg. dispose ();}

It seems that everything is right. The cursor is an image of a pure black background, because before writing data, the cursor did not reach the specified position. It is OK to add this sentence before unsafe:

 
Desimgdata. Seek (54 + 256*4, seekorigin. Begin); // the start position of the Data. See the bitmap file format description.

Let's see the effect:

Wow, what's the problem? Why is it? I saw the comments in my code prompt: No // The scanning is from top to bottom, and the storage is from bottom to top
The principle is not to mention. just replace the outer for loop parentheses with the comments.
This is okay. Is it true? Is it okay?
Open the "mm.bmp" Image in the bin directory on the canvas, and click "image" menu-> whether the attribute is 400 in width. Change it to 399 and press CTR + S to save it.
Then run the program:

Why can 400 be 399. It also involves 4 times the number of bytes.
Our pixel width is 400, right? 8 bits, 256 colors, one pixel, one byte, right? 400 bytes can be divisible by 4.
If you want to add a byte in 399 pixels to the outermost loop, this statement is OK:

 
Desimgdata. writebyte (0x00 );

No. You have to make him smarter and replace the code just now with this one:

 
Int fill = (srcimg. width * 8 + 31)/32*4)-srcimg. width; If (fill> 0) {byte [] fills = new byte [fill]; desimgdata. write (fills, 0, fills. length );}

After a successful success, an 8-Bit Bitmap named "gs.bmp" has been generated for the project. I am sorry for the fact that some of them are not perfect:

Sample file and code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.