[?] Re-Mapping an image
BlitzMax Forums/BlitzMax Programming/[?] Re-Mapping an image
| ||
Do you have a quick way to re-map the colors in an image to a preset pallete? Lets suppose I have loaded a typical 16 million color image and I want to change it's colors to a 4 color pallete of say: 0 - $000000 ' black 1 - $ffffff ' white 2 - $cc1211 ' red 3 - $32ef30 ' green What routine/function would you use? I have a modified GreyScale converter (Birdies) which is along the lines of what I'm trying to do: Function ConvertToGreyScale(i:TPixmap) For Local y=0 Until i.height For x=0 Until i.width Local col = ReadPixel( i, x, y ) Local a = ( col & $ff000000) Local r = ( col & $ff0000 ) Shr 16 Local g = ( col & $ff00 ) Shr 8 Local b = ( col & $ff ) Local cc= (r+g+b)/3 col = a | (cc Shl 16) | (cc Shl 8) | cc WritePixel i, x, y, col Next Next EndFunctionThe bit I'm stuck on is comparing the source pixel color with the available palette colors and choosing the nearest match. |
| ||
Well, i put already an example in the Wiki, http://www.blitzwiki.org/index.php/ReadPixel You can also try my GFX module: http://blempereur.einden.com/work/bmaxmod/ag.mod.rar The user guide online: http://blempereur.einden.com/work/bmaxmod/commands.html |
| ||
Are you planning on adding a 'RemapPixmap' function? That is, a function that will remap a pixmap to a fixed set of palette colors? BTW: Nice set of image manipulation functions. I'm still in a muddle. Should I compare each R,G,B component of the source pixel against the list colors in the palette or use the argb result? I need to find the closest matching color: argb=ReadPixel(mypixmap,x,y) For pal=EachIn PaletteList If pal.rgb {{is a close match to}} argb WritePixel mypixmap,x,y,pal.rgb EndIf Next |
| ||
Got it working by using:For pal=EachIn palettelist r=Abs(sourceRed-palRed) g=Abs(sourceGreen-palGreen) b=Abs(sourceBlue-palBlue) pal.index=(r+g+b)/3 Next After that, I sort the palettelist then pick off the first entry which is the closest match. |
| ||
If you finish any pixmap function, i can add it to my module, send me, you can write yourself the doc and explaination. Coz i'm not sure that i understand what you are trying to do. |
| ||
I have the re-mapping almost perfectly working now. It's just a matter of choosing an easy way to implement it into your image processing functions. The awkward part is how to pass the palette set. This is what my function does: Takes a loaded pixmap, re-maps the colours in the image to a preset range of colours from a palette. Example: ![]() As you can see, the remapping code needs more work. It fails to pick CYAN as a close match for the background. Currently, I have the palette stored in a TYPE with r,g,b fields. Basically, the routine just needs to run through a list of colours and choose the closest match. |
| ||
Maybe you would get a better color match using Hue Saturation and Value, rather than RGB? Also, how about dithering? Floyd Steinberg? That girl on the right looks ill ;-) |
| ||
Also, how about dithering? Floyd Steinberg? That girl on the right looks ill ;-) Or something from the C64 days. Not really surprising considering the chosen palette. |
| ||
Even with a limited palette it would look a lot more like the original with dithering, but then you have to look into building histograms of color usage and selecting an optimum palette. |
| ||
Or something from the C64 days. Not really surprising considering the chosen palette Well spotted that man. I'm doing a Retro screensaver which loads up an image from a given folder then converts it to a retro-style C64 screenie.So far it pretty much looks the business. Maybe you would get a better color match using Hue Saturation and Value I'm almost there with RGB but I'm sure there was a formula for matching 3 values to a list which contains sets of 3 values. Any ideas?What I'm doing at the moment is: argb=ReadPixel(i,x,y) srcR = (argb & $ff0000) Shr 16 srcG = (argb & $ff00) Shr 8 srcB = (argb & $ff) For pal=EachIn palettelist r=Abs(srcR-pal.r) g=Abs(srcG-pal.g) b=Abs(srcB-pal.b) pal.index=(r+g+b)/3 Next SortList palettelist ' lowest index value comes first fp:palette=palette(palettelist.first()) argb = $ff000000 | fp.r Shl 16 | fp.g Shl 8 | fp.b WritePixel i, x, y, argb I don't think this is the best way though. Example: source pixel color: ------------------------- 006,254,254 ' cyan palette choices: ------------------------- 092,250,253 ' cyan 158,251,171 ' light greenMy routine seems to choose light green here. |