Re: Finding nearest color of a predefined palette
From: Jerad Rose (no_at_spam.com)
Date: 01/24/05
- Previous message: Greg Chapman: "Re: GDI+ FAQ: Problem with best-fit transform and JPEG image"
- In reply to: Jerad Rose: "Re: Finding nearest color of a predefined palette"
- Messages sorted by: [ date ] [ thread ]
Date: Mon, 24 Jan 2005 16:53:06 -0500
Wow, I think I just found exactly what I was looking for.
I continued checking out your other FAQs, and ran across your FAQ on
"Creating an optimized palette for GIF images", which led me to this MSDN
article:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/colorquant.asp
There it shows me how to determine the "distance" between two colors --
which I see now is just the sum of each RGB difference sqaured:
Dim redDistance As Integer = OriginalColor.R - clr.R
Dim greenDistance As Integer = OriginalColor.G - clr.G
Dim blueDistance As Integer = OriginalColor.B - clr.B
Dim distance = _
(redDistance * redDistance) + _
(greenDistance * greenDistance) + _
(blueDistance * blueDistance)
Now, after realizing I can't use SetPixel on an indexed bitmap, I'm back to
having to use the LockBits method in this article:
http://support.microsoft.com/default.aspx?scid=kb;en-us;319591
Wow. This seems like a lot of work for something that you would think
simple. At any rate, I'm about there, and I'm happy.
Thanks again, and hope this helps others that may run into this.
Jerad
"Jerad Rose" <no@spam.com> wrote in message
news:uOwibOlAFHA.3820@TK2MSFTNGP11.phx.gbl...
> Ok Bob (or whoever else could help), quick question.
>
> It looks like, in your FAQ (Creating Transparent GIF Images), you're using
> the same source and destination palettes, with the exception that you
choose
> and set the index for the transparent color.
>
> So, while it looks like I can use your example to transfer the source
image
> (that can be any format, size, and color depth) to the destination image
> (which will be 32x32, indexed 4bpp [16-color]), I still am not sure how to
> do the color transformation, finding the nearest match from the 16-color
> palette. I'm not even concerned about saving the file (these images will
> not be saved as files, but rather into a database as a 1024 string of hex
> characters representing the palette indexes). I'm just trying to figure
out
> how to do the color tranformation from a 32bpp color depth, to a 4bpp
color
> depth w/ a predefined palette.
>
> For example, I need something like this:
>
> --------------------------------------------------------------------------
-- > ------------- > Function CopyPixelsIntoNewPalette( _ > ByVal SourceImage As Bitmap, _ > ByVal NewPalette As ColorPalette) As Bitmap > Dim x As Integer, y As Integer > > Dim bmp As Bitmap = New Bitmap(32, 32, > PixelFormat.Format4bppIndexed) > Dim clrClosestMatch As Color > > For x = 0 To 31 > For y = 0 To 31 > clrClosestMatch = FindNearestMatchInPalette(NewPalette, > SourceImage.GetPixel(x, y)) > bmp.SetPixel(x, y, clrClosestMatch) > Next > Next > End Function > > Function FindNearestMatchInPalette( _ > ByVal SourcePalette As ColorPalette, _ > ByVal OriginalColor As Color) As Color > Dim clr As Color > Dim ClosestColor As Color > > For Each clr In SourcePalette.Entries > If DifferenceBetweenColors(clr, OriginalColor) < _ > DifferenceBetweenColors(ClosestColor, OriginalColor) > Then > ClosestColor = clr > End If > Next > End Function > > Function DifferenceBetweenColors(ByVal clr, ByVal OriginalColor) As Long > ' Some code here to calculate how close one color is to another > End Function > -------------------------------------------------------------------------- -- > ------------- > > But figuring out the algorithm for comparing colors and determining which > color is a closest match is what I can't figure out. > > Maybe I'm just totally missing something here. Like, is one of your > examples doing the work for me (saving the file w/ a new palette > automatically sets each pixel to the closest match for the palette)? If so, > that would be great too. But if I have to do the work of matching an > arbitrary color to one of 16 colors in a palette, then that's what I'm > trying to figure out. > > Thanks again for your help -- it's much appreciated. > > Jerad > > > "Jerad Rose" <no@spam.com> wrote in message > news:uA568hiAFHA.4044@TK2MSFTNGP10.phx.gbl... > > Thanks Bob for your response. > > > > I will be checking out your site, starting w/ the GDI+ Beginners Guide, > > since I still feel fairly new at all this. I'm typically a business > > developer and have not had much exposure to the graphical side of .NET -- > > though, I'm enjoying it quite a bit. > > > > If you don't mind, keep an eye on this thread over the next week or so, so > > that I may hit you up w/ other questions I may have after reading the > guides > > you suggested. > > > > Thanks again for your help. > > > > Jerad > > > > "Bob Powell [MVP]" <bob@_spamkiller_bobpowell.net> wrote in message > > news:uC1nVtgAFHA.3824@TK2MSFTNGP10.phx.gbl... > > > There is an article in the GDI+ FAQ that explains how to modify the > > > transparent colour in a palette. This shows you how to alter the palette > > in > > > any 8 bpp image. You should be able to adapt this for your needs. There > is > > > also an article on LockBits that explains how that works if you're > > > interested. > > > > > > -- > > > Bob Powell [MVP] > > > Visual C#, System.Drawing > > > > > > Find great Windows Forms articles in Windows Forms Tips and Tricks > > > http://www.bobpowell.net/tipstricks.htm > > > > > > Answer those GDI+ questions with the GDI+ FAQ > > > http://www.bobpowell.net/faqmain.htm > > > > > > All new articles provide code in C# and VB.NET. > > > Subscribe to the RSS feeds provided and never miss a new article. > > > > > > > > > > > > > > > > > > "Jerad Rose" <no@spam.com> wrote in message > > > news:eJEfmYcAFHA.1296@TK2MSFTNGP10.phx.gbl... > > > >I have a seemingly simple problem that I've been unable to find the > > > >solution > > > > for. > > > > > > > > I have 15 sets of predefined palettes, each having 15 colors. All I'm > > > > trying to do, is load images (jpg, gif, or bmp) or any size into a > 32x32 > > > > 15-color image. I know how to resize the image to a 32x32 bitmap, but > > > > then > > > > I want this image to be "fitted" into these 15-color palettes, using > the > > > > nearest matching color for each pixel from a given palette. > > > > > > > > I think I know how to build my palette for my bitmap: > > > > > > > > Public Function GetPaletteOfIndex(ByVal iPaletteIndex As Integer) > As > > > > ColorPalette > > > > Dim bmp As Bitmap = New Bitmap(1, 1, > > PixelFormat.Format8bppIndexed) > > > > Dim pal As ColorPalette = bmp.Palette > > > > > > > > Dim i As Integer > > > > For i = 0 To 14 > > > > 'clrPalette is a preset 15x15 array of Color objects > > > > pal.Entries(i) = clrPalette(iPaletteIndex, i) > > > > Next > > > > > > > > 'set the 16th (unused) Entry to transparent > > > > pal.Entries(15) = Color.FromArgb(0) > > > > bmp.Dispose() > > > > Return pal > > > > End Function > > > > > > > > I'm just not sure where to go from here. I've tried loading an image > > into > > > > the bitmap predefined w/ this palette, but I think instead of it using > > the > > > > predefined palette, it overwrites it w/ the palette from the file. > I've > > > > also tried drawing an image into the bitmap w/ the predefined palette, > > but > > > > you can't use Graphics from an 8bpp bitmap. > > > > > > > > I've read this article: > > > > http://support.microsoft.com/?id=319061 > > > > > > > > ... but it looks like it's calculating the "nearest color" on its own > > (and > > > > this example is using a grayscale palette). Plus, the memory stuff > > there > > > > (LockBits, Scan0, Stride) kinda loses me -- surely all that isn't > > > > necessary > > > > for what I'm trying to do. > > > > > > > > I've searched on the Graphics.GetNearestColor function, which seems > like > > > > it > > > > would be what I need, but I'm unsure what it's getting the nearest > color > > > > *of*. It would be perfect if this function was a member of the > > > > ColorPalette > > > > object, and it would just return the closest match for that color in > > that > > > > palette, but alas, this function is on the Graphics object (which > can't > > be > > > > obtained on anything other than a 32bpp bitmap). So I'm not even sure > > in > > > > what case I would use the GetNearestColor function. > > > > > > > > So, is what I'm trying to do really that difficult to accomplish? I > > would > > > > think this would be a fairly common practice, and not that difficult > to > > > > pull > > > > off. > > > > > > > > Thanks so much in advance for any help. > > > > > > > > Jerad > > > > > > > > > > > > > > > > > > > >
- Previous message: Greg Chapman: "Re: GDI+ FAQ: Problem with best-fit transform and JPEG image"
- In reply to: Jerad Rose: "Re: Finding nearest color of a predefined palette"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|