473,796 Members | 2,618 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

The ColorPalette class has no constructor so how does one use it?

The ColorPalette class has no constructor so how does one use it?
I define a variable by:

Dim cp as ColorPalette

but don't know how assign an object to the variable.

Thanks in advance


Jul 14 '07
19 2436

Have a look at
http://www.codeproject.com/cs/media/...essing_Lab.asp

To create a grayscale image from a 256-color image, he creates
a new 8-bit image of the same size as the original, sets the Palette
values of the new image to 0,0,0 1,1,1 2,2,2 ... 255,255,255,
then proceeds to set the pixel data of the new image by calculating
the intensities of the original image.

It would have been much faster had he just modified the palette
entries of the original image.

I made another test (create a new Windows application project):
---snip---
Private _bm As Bitmap

Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Load
Test2()
End Sub

Private Sub Test2()
Dim lena8 As New Bitmap("d:\lena 8.bmp")
SetGrayscalePal ette(lena8)
_bm = lena8
lena8.Save("d:\ lena8-gray.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)
End Sub

Public Shared Sub SetGrayscalePal ette(ByVal image As Bitmap)
If (image.PixelFor mat <PixelFormat.Fo rmat8bppIndexed ) Then
Throw New ArgumentExcepti on
End If
Dim palette As ColorPalette = image.Palette
Dim i As Integer
For i = 0 To &H100 - 1
'palette.Entrie s(i) = Color.FromArgb( i, i, i)
Dim original As Color = palette.Entries (i)
Dim gray As Integer = CType((original .G * 4 + original.R *
2 + original.B) / 7, Integer)
palette.Entries (i) = Color.FromArgb( gray, gray, gray)
Next i
image.Palette = palette
End Sub

Private Sub Form1_Paint(ByV al sender As Object, ByVal e As
System.Windows. Forms.PaintEven tArgs) Handles Me.Paint
If _bm Is Nothing Then
Exit Sub
End If

e.Graphics.Draw Image(_bm, 0, 0, _bm.Width, _bm.Height)

End Sub

---snip---

(Yes, I know that (G*4+R*2+B)/7 is simplistic and incorrect)

You will notice that the palette entries actually have changed when
the image is painted on the form, but the saved copy retains the
original colors.

If we were to paint the image from the code above onto a 24-bit
bitmap and save it, we get a nice grayscale image, albeit 24-bit:
---snip---
Dim dst As New Bitmap(lena8.Wi dth, lena8.Height,
PixelFormat.For mat24bppRgb)
Dim g As Graphics = Graphics.FromIm age(dst)
g.DrawImage(len a8, 0, 0, dst.Width, dst.Height)
g.Dispose()
dst.Save("d:\ds t.bmp", ImageFormat.Bmp )
---snip---

(it is not possible to create a Graphics object from an indexed
image).

I have not spent any time digging into why the original palette
is used when saving an indexed image, but as I mentioned in the
other post, I use an imaging library myself (LeadTools).

Perhaps the link at the top might give you a few ideas of how
to go about this in an entirely different way.

Regards,

Joergen Bech

On Sat, 14 Jul 2007 21:37:24 -0400, " active"
<ac********** @a-znet.comwrote:
>What was MS thinking?
Why not make Entries readonly?
I add a statement to yout code:
The line written did not reflect i,i,i

lena8.Palette. Entries(i) = Color.FromArgb( i, i, i)

Console.WriteL ine("Entry({0} = {1}", i, lena8.Palette.E ntries(i))


"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:5n******* *************** **********@4ax. com...
>>
My suggestion was that if you needed a class
with the same behavior as ColorPalette, but with
a few changes, you could just copy the code from
the ColorPalette class to another class with the
name and additional functionality of your choice.
There are various tools for decompiling the framework.

But if you need to assign a ColorPalette object
to a property that expects the type found in the
framework, this might not be an option.

As for assigning a palette from a dummy palette
indirectly created by creating a new bitmap of the
same bit depth: No can do.

MyBitmap.Palet te = <ColorPalette object>

is not the same as

MyBitmap.Palet te = <some other bitmap>.Palette .

In the latter case, you are going through some
GDI+ functions to get a new palette rather than
just getting a ColorPalette object directly.

When assigned to MyBitmap.Palett e, you are
jumping through similar hoops.

Try the code below. You will find that nothing
works as expected. All copies are identical to
the original. Attempts to change the colors in
any of these manners are ignored.

I use an imaging toolkit for similar needs, so I
haven't digged deeper into this. There might be
a solution. Then again, there might not. It is possible
that Microsoft has made it *possible* to change the
Palette.Entrie s values, but not *intended* for them
to be changed or react to such changes.

Please prove me wrong.

Regards,

Joergen Bech

---snip---

'Load image
Dim lena8 As New Bitmap("d:\lena 8.bmp")

'Save it again to verify that we read it correctly
lena8.Save("d:\ lena8-original.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Work with a palette created as a copy of the palette of the
original image
Dim cp As ColorPalette = lena8.Palette

For i As Integer = 0 To 255
cp.Entries(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = cp
lena8.Save("d:\ lena8-cp.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Work with a dummy palette created by creating another bitmap
Dim bm As New Bitmap(1, 1, PixelFormat.For mat8bppIndexed)
For i As Integer = 0 To 255
bm.Palette.Entr ies(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = bm.Palette
lena8.Save("d:\ lena8-bm.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Modify palette entries directly in the original image
For i As Integer = 0 To 255
lena8.Palette.E ntries(i) = Color.FromArgb( i, i, i)
Next
lena8.Save("d:\ lena8-0-255.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

---snip---

On Sat, 14 Jul 2007 17:31:09 -0400, " active"
<ac**********@ a-znet.comwrote:
>>>For each entry:
get an entry from a Bitmap color table
modify it
store the modified entry in a color table
Assign the new color table to the bitmap.

So I think I can do what the other posters suggested.

But I would like to know what you meant by the following.

Just copy the class to MyColorPalette
Thanks
Jul 15 '07 #11
How dose powell get a way with this.
It works including saving to a file.
The last line I show he is inserting a color table into a Bitmap!
He then inserts the bitmap data.

Isn't this what we are saying can't be effective?

Thanks if you can explain this
Private Sub panel1_Click(.. .
'Creates a new GIF image with a modified colour palette

If Not (cp Is Nothing) Then

'Create a new 8 bit per pixel image

Dim bm As New Bitmap(_gifImag e.Width, _gifImage.Heigh t,
PixelFormat.For mat8bppIndexed)

'get it's palette

Dim ncp As ColorPalette = bm.Palette

'copy all the entries from the old palette removing any transparency

Dim n As Integer = 0

Dim c As Color

For Each c In cp.Entries

ncp.Entries(n) = Color.FromArgb( 255, c)

n += 1

Next c

'Set the newly selected transparency

ncp.Entries(Cur rentEntry) = Color.FromArgb( 0,
cp.Entries(Curr entEntry))

're-insert the palette

bm.Palette = ncp



"Joergen Bech @ post1.tele.dk>" wrote:
>
Have a look at
http://www.codeproject.com/cs/media/...essing_Lab.asp

To create a grayscale image from a 256-color image, he creates
a new 8-bit image of the same size as the original, sets the Palette
values of the new image to 0,0,0 1,1,1 2,2,2 ... 255,255,255,
then proceeds to set the pixel data of the new image by calculating
the intensities of the original image.

It would have been much faster had he just modified the palette
entries of the original image.

I made another test (create a new Windows application project):
---snip---
Private _bm As Bitmap

Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
System.EventArg s) Handles MyBase.Load
Test2()
End Sub

Private Sub Test2()
Dim lena8 As New Bitmap("d:\lena 8.bmp")
SetGrayscalePal ette(lena8)
_bm = lena8
lena8.Save("d:\ lena8-gray.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)
End Sub

Public Shared Sub SetGrayscalePal ette(ByVal image As Bitmap)
If (image.PixelFor mat <PixelFormat.Fo rmat8bppIndexed ) Then
Throw New ArgumentExcepti on
End If
Dim palette As ColorPalette = image.Palette
Dim i As Integer
For i = 0 To &H100 - 1
'palette.Entrie s(i) = Color.FromArgb( i, i, i)
Dim original As Color = palette.Entries (i)
Dim gray As Integer = CType((original .G * 4 + original.R *
2 + original.B) / 7, Integer)
palette.Entries (i) = Color.FromArgb( gray, gray, gray)
Next i
image.Palette = palette
End Sub

Private Sub Form1_Paint(ByV al sender As Object, ByVal e As
System.Windows. Forms.PaintEven tArgs) Handles Me.Paint
If _bm Is Nothing Then
Exit Sub
End If

e.Graphics.Draw Image(_bm, 0, 0, _bm.Width, _bm.Height)

End Sub

---snip---

(Yes, I know that (G*4+R*2+B)/7 is simplistic and incorrect)

You will notice that the palette entries actually have changed when
the image is painted on the form, but the saved copy retains the
original colors.

If we were to paint the image from the code above onto a 24-bit
bitmap and save it, we get a nice grayscale image, albeit 24-bit:
---snip---
Dim dst As New Bitmap(lena8.Wi dth, lena8.Height,
PixelFormat.For mat24bppRgb)
Dim g As Graphics = Graphics.FromIm age(dst)
g.DrawImage(len a8, 0, 0, dst.Width, dst.Height)
g.Dispose()
dst.Save("d:\ds t.bmp", ImageFormat.Bmp )
---snip---

(it is not possible to create a Graphics object from an indexed
image).

I have not spent any time digging into why the original palette
is used when saving an indexed image, but as I mentioned in the
other post, I use an imaging library myself (LeadTools).

Perhaps the link at the top might give you a few ideas of how
to go about this in an entirely different way.

Regards,

Joergen Bech

On Sat, 14 Jul 2007 21:37:24 -0400, " active"
<ac********** @a-znet.comwrote:
What was MS thinking?
Why not make Entries readonly?
I add a statement to yout code:
The line written did not reflect i,i,i

lena8.Palette.E ntries(i) = Color.FromArgb( i, i, i)

Console.WriteLi ne("Entry({0} = {1}", i, lena8.Palette.E ntries(i))


"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:5n******** *************** *********@4ax.c om...
>
My suggestion was that if you needed a class
with the same behavior as ColorPalette, but with
a few changes, you could just copy the code from
the ColorPalette class to another class with the
name and additional functionality of your choice.
There are various tools for decompiling the framework.

But if you need to assign a ColorPalette object
to a property that expects the type found in the
framework, this might not be an option.

As for assigning a palette from a dummy palette
indirectly created by creating a new bitmap of the
same bit depth: No can do.

MyBitmap.Palett e = <ColorPalette object>

is not the same as

MyBitmap.Palett e = <some other bitmap>.Palette .

In the latter case, you are going through some
GDI+ functions to get a new palette rather than
just getting a ColorPalette object directly.

When assigned to MyBitmap.Palett e, you are
jumping through similar hoops.

Try the code below. You will find that nothing
works as expected. All copies are identical to
the original. Attempts to change the colors in
any of these manners are ignored.

I use an imaging toolkit for similar needs, so I
haven't digged deeper into this. There might be
a solution. Then again, there might not. It is possible
that Microsoft has made it *possible* to change the
Palette.Entries values, but not *intended* for them
to be changed or react to such changes.

Please prove me wrong.

Regards,

Joergen Bech

---snip---

'Load image
Dim lena8 As New Bitmap("d:\lena 8.bmp")

'Save it again to verify that we read it correctly
lena8.Save("d:\ lena8-original.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)

'Work with a palette created as a copy of the palette of the
original image
Dim cp As ColorPalette = lena8.Palette

For i As Integer = 0 To 255
cp.Entries(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = cp
lena8.Save("d:\ lena8-cp.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)

'Work with a dummy palette created by creating another bitmap
Dim bm As New Bitmap(1, 1, PixelFormat.For mat8bppIndexed)
For i As Integer = 0 To 255
bm.Palette.Entr ies(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = bm.Palette
lena8.Save("d:\ lena8-bm.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)

'Modify palette entries directly in the original image
For i As Integer = 0 To 255
lena8.Palette.E ntries(i) = Color.FromArgb( i, i, i)
Next
lena8.Save("d:\ lena8-0-255.bmp",
System.Drawing. Imaging.ImageFo rmat.Bmp)

---snip---

On Sat, 14 Jul 2007 17:31:09 -0400, " active"
<ac********** @a-znet.comwrote:

For each entry:
get an entry from a Bitmap color table
modify it
store the modified entry in a color table
Assign the new color table to the bitmap.

So I think I can do what the other posters suggested.

But I would like to know what you meant by the following.

Just copy the class to MyColorPalette
Thanks


Aug 20 '07 #12

If my memory serves me right, the original problem was that
if the 8-bit indexed image was loaded from a file, any attempt
(at least any attempt I made) would fail to change the palette.

In your (Powell's) example, you are creating a NEW bitmap
object, then setting the palette - which actually works - but
that is not as interesting as changing the palette for an
existing image we just loaded.

As you say, the last line you show sets the palette for the
bitmap object, but you fail to show how Powell "inserts the
bitmap data"?!?

Could you please post a complete, working sample based
on this information that actually loads a gif from disk, changes
the palette, then writes it back to disk, changed palette and all?

Regards,

Joergen Bech

On Mon, 20 Aug 2007 11:20:03 -0700, active
<ac****@discuss ions.microsoft. comwrote:
>How dose powell get a way with this.
It works including saving to a file.
The last line I show he is inserting a color table into a Bitmap!
He then inserts the bitmap data.

Isn't this what we are saying can't be effective?

Thanks if you can explain this
Private Sub panel1_Click(.. .
'Creates a new GIF image with a modified colour palette

If Not (cp Is Nothing) Then

'Create a new 8 bit per pixel image

Dim bm As New Bitmap(_gifImag e.Width, _gifImage.Heigh t,
PixelFormat.Fo rmat8bppIndexed )

'get it's palette

Dim ncp As ColorPalette = bm.Palette

'copy all the entries from the old palette removing any transparency

Dim n As Integer = 0

Dim c As Color

For Each c In cp.Entries

ncp.Entries(n) = Color.FromArgb( 255, c)

n += 1

Next c

'Set the newly selected transparency

ncp.Entries(Cur rentEntry) = Color.FromArgb( 0,
cp.Entries(Cur rentEntry))

're-insert the palette

bm.Palette = ncp



"Joergen Bech @ post1.tele.dk>" wrote:
>>
Have a look at
http://www.codeproject.com/cs/media/...essing_Lab.asp

To create a grayscale image from a 256-color image, he creates
a new 8-bit image of the same size as the original, sets the Palette
values of the new image to 0,0,0 1,1,1 2,2,2 ... 255,255,255,
then proceeds to set the pixel data of the new image by calculating
the intensities of the original image.

It would have been much faster had he just modified the palette
entries of the original image.

I made another test (create a new Windows application project):
---snip---
Private _bm As Bitmap

Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
System.EventAr gs) Handles MyBase.Load
Test2()
End Sub

Private Sub Test2()
Dim lena8 As New Bitmap("d:\lena 8.bmp")
SetGrayscalePal ette(lena8)
_bm = lena8
lena8.Save("d:\ lena8-gray.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)
End Sub

Public Shared Sub SetGrayscalePal ette(ByVal image As Bitmap)
If (image.PixelFor mat <PixelFormat.Fo rmat8bppIndexed ) Then
Throw New ArgumentExcepti on
End If
Dim palette As ColorPalette = image.Palette
Dim i As Integer
For i = 0 To &H100 - 1
'palette.Entrie s(i) = Color.FromArgb( i, i, i)
Dim original As Color = palette.Entries (i)
Dim gray As Integer = CType((original .G * 4 + original.R *
2 + original.B) / 7, Integer)
palette.Entries (i) = Color.FromArgb( gray, gray, gray)
Next i
image.Palette = palette
End Sub

Private Sub Form1_Paint(ByV al sender As Object, ByVal e As
System.Windows .Forms.PaintEve ntArgs) Handles Me.Paint
If _bm Is Nothing Then
Exit Sub
End If

e.Graphics.Draw Image(_bm, 0, 0, _bm.Width, _bm.Height)

End Sub

---snip---

(Yes, I know that (G*4+R*2+B)/7 is simplistic and incorrect)

You will notice that the palette entries actually have changed when
the image is painted on the form, but the saved copy retains the
original colors.

If we were to paint the image from the code above onto a 24-bit
bitmap and save it, we get a nice grayscale image, albeit 24-bit:
---snip---
Dim dst As New Bitmap(lena8.Wi dth, lena8.Height,
PixelFormat.Fo rmat24bppRgb)
Dim g As Graphics = Graphics.FromIm age(dst)
g.DrawImage(len a8, 0, 0, dst.Width, dst.Height)
g.Dispose()
dst.Save("d:\ds t.bmp", ImageFormat.Bmp )
---snip---

(it is not possible to create a Graphics object from an indexed
image).

I have not spent any time digging into why the original palette
is used when saving an indexed image, but as I mentioned in the
other post, I use an imaging library myself (LeadTools).

Perhaps the link at the top might give you a few ideas of how
to go about this in an entirely different way.

Regards,

Joergen Bech

On Sat, 14 Jul 2007 21:37:24 -0400, " active"
<ac**********@ a-znet.comwrote:
>What was MS thinking?
Why not make Entries readonly?
I add a statement to yout code:
The line written did not reflect i,i,i

lena8.Palette. Entries(i) = Color.FromArgb( i, i, i)

Console.WriteL ine("Entry({0} = {1}", i, lena8.Palette.E ntries(i))


"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:5n******* *************** **********@4ax. com...

My suggestion was that if you needed a class
with the same behavior as ColorPalette, but with
a few changes, you could just copy the code from
the ColorPalette class to another class with the
name and additional functionality of your choice.
There are various tools for decompiling the framework.

But if you need to assign a ColorPalette object
to a property that expects the type found in the
framework, this might not be an option.

As for assigning a palette from a dummy palette
indirectly created by creating a new bitmap of the
same bit depth: No can do.

MyBitmap.Palet te = <ColorPalette object>

is not the same as

MyBitmap.Palet te = <some other bitmap>.Palette .

In the latter case, you are going through some
GDI+ functions to get a new palette rather than
just getting a ColorPalette object directly.

When assigned to MyBitmap.Palett e, you are
jumping through similar hoops.

Try the code below. You will find that nothing
works as expected. All copies are identical to
the original. Attempts to change the colors in
any of these manners are ignored.

I use an imaging toolkit for similar needs, so I
haven't digged deeper into this. There might be
a solution. Then again, there might not. It is possible
that Microsoft has made it *possible* to change the
Palette.Entrie s values, but not *intended* for them
to be changed or react to such changes.

Please prove me wrong.

Regards,

Joergen Bech

---snip---

'Load image
Dim lena8 As New Bitmap("d:\lena 8.bmp")

'Save it again to verify that we read it correctly
lena8.Save("d:\ lena8-original.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Work with a palette created as a copy of the palette of the
original image
Dim cp As ColorPalette = lena8.Palette

For i As Integer = 0 To 255
cp.Entries(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = cp
lena8.Save("d:\ lena8-cp.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Work with a dummy palette created by creating another bitmap
Dim bm As New Bitmap(1, 1, PixelFormat.For mat8bppIndexed)
For i As Integer = 0 To 255
bm.Palette.Entr ies(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = bm.Palette
lena8.Save("d:\ lena8-bm.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

'Modify palette entries directly in the original image
For i As Integer = 0 To 255
lena8.Palette.E ntries(i) = Color.FromArgb( i, i, i)
Next
lena8.Save("d:\ lena8-0-255.bmp",
System.Drawing .Imaging.ImageF ormat.Bmp)

---snip---

On Sat, 14 Jul 2007 17:31:09 -0400, " active"
<ac**********@ a-znet.comwrote:

For each entry:
get an entry from a Bitmap color table
modify it
store the modified entry in a color table
Assign the new color table to the bitmap.

So I think I can do what the other posters suggested.

But I would like to know what you meant by the following.

Just copy the class to MyColorPalette
Thanks

Aug 21 '07 #13
I believe I just found the answer in Q319061.
....snip
You can write an unmodified Bitmap with the GIF encoder and keep the Bitmap
color table intact; therefore, you can use this method to save a .gif file
with a new color table.

The method is to copy the image data from an original Image object to a
temporary Bitmap object. This temporary Bitmap is created as an 8-BPP
indexed Bitmap, which is the pixel format that is used to save a .gif file.
The Bitmap color table is set by using the SetPalette method, and then the
image definition is copied to the temporary Bitmap. After you create the
temporary Bitmap with a duplicate definition, you can use the Save() method
to save it with the GIF encoder, which preserves the 8-BPP color table.
...snip

I guess the "unmodified " is what allows it. Maybe when the bitmap data is
added the "save" color table get frozen. You think?

Q319061 shows how and I believe it is just what Powell does.

Code is at the bottom of this link in the panel1_Click sub at

http://www.bobpowell.net/giftransparency.htm

====

Do you know why it is always 8bpp. Other formats such as 4bpp are possible
but never seem to be saved by GDI+
Also, I found Q319061 when I was looking for the file format for a GIF file
(read via a stream) if you know where that is I'd appreciate the link.
Thanks for answering

"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:7q******** *************** *********@4ax.c om...
>
If my memory serves me right, the original problem was that
if the 8-bit indexed image was loaded from a file, any attempt
(at least any attempt I made) would fail to change the palette.

In your (Powell's) example, you are creating a NEW bitmap
object, then setting the palette - which actually works - but
that is not as interesting as changing the palette for an
existing image we just loaded.

He copies the image data so it creates a new bitmap with the same image an a
new palette which can be saved and viewed.
>
As you say, the last line you show sets the palette for the
bitmap object, but you fail to show how Powell "inserts the
bitmap data"?!?
It's a little long and I don't know if that is OK with Powell.
>
Could you please post a complete, working sample based
on this information that actually loads a gif from disk, changes
the palette, then writes it back to disk, changed palette and all?
He plays with the transparency but that can be removed.
>
Regards,

Joergen Bech

On Mon, 20 Aug 2007 11:20:03 -0700, active
<ac****@discuss ions.microsoft. comwrote:
>>How dose powell get a way with this.
It works including saving to a file.
The last line I show he is inserting a color table into a Bitmap!
He then inserts the bitmap data.

Isn't this what we are saying can't be effective?

Thanks if you can explain this
Private Sub panel1_Click(.. .
'Creates a new GIF image with a modified colour palette

If Not (cp Is Nothing) Then

'Create a new 8 bit per pixel image

Dim bm As New Bitmap(_gifImag e.Width, _gifImage.Heigh t,
PixelFormat.F ormat8bppIndexe d)

'get it's palette

Dim ncp As ColorPalette = bm.Palette

'copy all the entries from the old palette removing any
transparency

Dim n As Integer = 0

Dim c As Color

For Each c In cp.Entries

ncp.Entries(n) = Color.FromArgb( 255, c)

n += 1

Next c

'Set the newly selected transparency

ncp.Entries(Cur rentEntry) = Color.FromArgb( 0,
cp.Entries(Cu rrentEntry))

're-insert the palette

bm.Palette = ncp



"Joergen Bech @ post1.tele.dk>" wrote:
>>>
Have a look at
http://www.codeproject.com/cs/media/...essing_Lab.asp

To create a grayscale image from a 256-color image, he creates
a new 8-bit image of the same size as the original, sets the Palette
values of the new image to 0,0,0 1,1,1 2,2,2 ... 255,255,255,
then proceeds to set the pixel data of the new image by calculating
the intensities of the original image.

It would have been much faster had he just modified the palette
entries of the original image.

I made another test (create a new Windows application project):
---snip---
Private _bm As Bitmap

Private Sub Form1_Load(ByVa l sender As System.Object, ByVal e As
System.EventA rgs) Handles MyBase.Load
Test2()
End Sub

Private Sub Test2()
Dim lena8 As New Bitmap("d:\lena 8.bmp")
SetGrayscalePal ette(lena8)
_bm = lena8
lena8.Save("d:\ lena8-gray.bmp",
System.Drawin g.Imaging.Image Format.Bmp)
End Sub

Public Shared Sub SetGrayscalePal ette(ByVal image As Bitmap)
If (image.PixelFor mat <PixelFormat.Fo rmat8bppIndexed ) Then
Throw New ArgumentExcepti on
End If
Dim palette As ColorPalette = image.Palette
Dim i As Integer
For i = 0 To &H100 - 1
'palette.Entrie s(i) = Color.FromArgb( i, i, i)
Dim original As Color = palette.Entries (i)
Dim gray As Integer = CType((original .G * 4 + original.R *
2 + original.B) / 7, Integer)
palette.Entries (i) = Color.FromArgb( gray, gray, gray)
Next i
image.Palette = palette
End Sub

Private Sub Form1_Paint(ByV al sender As Object, ByVal e As
System.Window s.Forms.PaintEv entArgs) Handles Me.Paint
If _bm Is Nothing Then
Exit Sub
End If

e.Graphics.Draw Image(_bm, 0, 0, _bm.Width, _bm.Height)

End Sub

---snip---

(Yes, I know that (G*4+R*2+B)/7 is simplistic and incorrect)

You will notice that the palette entries actually have changed when
the image is painted on the form, but the saved copy retains the
original colors.

If we were to paint the image from the code above onto a 24-bit
bitmap and save it, we get a nice grayscale image, albeit 24-bit:
---snip---
Dim dst As New Bitmap(lena8.Wi dth, lena8.Height,
PixelFormat.F ormat24bppRgb)
Dim g As Graphics = Graphics.FromIm age(dst)
g.DrawImage(len a8, 0, 0, dst.Width, dst.Height)
g.Dispose()
dst.Save("d:\ds t.bmp", ImageFormat.Bmp )
---snip---

(it is not possible to create a Graphics object from an indexed
image).

I have not spent any time digging into why the original palette
is used when saving an indexed image, but as I mentioned in the
other post, I use an imaging library myself (LeadTools).

Perhaps the link at the top might give you a few ideas of how
to go about this in an entirely different way.

Regards,

Joergen Bech

On Sat, 14 Jul 2007 21:37:24 -0400, " active"
<ac********** @a-znet.comwrote:

What was MS thinking?
Why not make Entries readonly?
I add a statement to yout code:
The line written did not reflect i,i,i

lena8.Palette .Entries(i) = Color.FromArgb( i, i, i)

Console.Write Line("Entry({0} = {1}", i, lena8.Palette.E ntries(i))


"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:5n****** *************** ***********@4ax .com...

My suggestion was that if you needed a class
with the same behavior as ColorPalette, but with
a few changes, you could just copy the code from
the ColorPalette class to another class with the
name and additional functionality of your choice.
There are various tools for decompiling the framework.

But if you need to assign a ColorPalette object
to a property that expects the type found in the
framework, this might not be an option.

As for assigning a palette from a dummy palette
indirectly created by creating a new bitmap of the
same bit depth: No can do.

MyBitmap.Pale tte = <ColorPalette object>

is not the same as

MyBitmap.Pale tte = <some other bitmap>.Palette .

In the latter case, you are going through some
GDI+ functions to get a new palette rather than
just getting a ColorPalette object directly.

When assigned to MyBitmap.Palett e, you are
jumping through similar hoops.

Try the code below. You will find that nothing
works as expected. All copies are identical to
the original. Attempts to change the colors in
any of these manners are ignored.

I use an imaging toolkit for similar needs, so I
haven't digged deeper into this. There might be
a solution. Then again, there might not. It is possible
that Microsoft has made it *possible* to change the
Palette.Entri es values, but not *intended* for them
to be changed or react to such changes.

Please prove me wrong.

Regards,

Joergen Bech

---snip---

'Load image
Dim lena8 As New Bitmap("d:\lena 8.bmp")

'Save it again to verify that we read it correctly
lena8.Save("d:\ lena8-original.bmp",
System.Drawin g.Imaging.Image Format.Bmp)

'Work with a palette created as a copy of the palette of the
original image
Dim cp As ColorPalette = lena8.Palette

For i As Integer = 0 To 255
cp.Entries(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = cp
lena8.Save("d:\ lena8-cp.bmp",
System.Drawin g.Imaging.Image Format.Bmp)

'Work with a dummy palette created by creating another bitmap
Dim bm As New Bitmap(1, 1, PixelFormat.For mat8bppIndexed)
For i As Integer = 0 To 255
bm.Palette.Entr ies(i) = Color.FromArgb( i, i, i)
Next
lena8.Palette = bm.Palette
lena8.Save("d:\ lena8-bm.bmp",
System.Drawin g.Imaging.Image Format.Bmp)

'Modify palette entries directly in the original image
For i As Integer = 0 To 255
lena8.Palette.E ntries(i) = Color.FromArgb( i, i, i)
Next
lena8.Save("d:\ lena8-0-255.bmp",
System.Drawin g.Imaging.Image Format.Bmp)

---snip---

On Sat, 14 Jul 2007 17:31:09 -0400, " active"
<ac********** @a-znet.comwrote:

For each entry:
get an entry from a Bitmap color table
modify it
store the modified entry in a color table
Assign the new color table to the bitmap.

So I think I can do what the other posters suggested.

But I would like to know what you meant by the following.

Just copy the class to MyColorPalette
Thanks



Aug 21 '07 #14
On Tue, 21 Aug 2007 13:51:05 -0400, "\"Frank\"" <Fr***@a-znet.com>
wrote:
>I believe I just found the answer in Q319061.
...snip
You can write an unmodified Bitmap with the GIF encoder and keep the Bitmap
color table intact; therefore, you can use this method to save a .gif file
with a new color table.

The method is to copy the image data from an original Image object to a
temporary Bitmap object. This temporary Bitmap is created as an 8-BPP
indexed Bitmap, which is the pixel format that is used to save a .gif file.
The Bitmap color table is set by using the SetPalette method, and then the
image definition is copied to the temporary Bitmap. After you create the
temporary Bitmap with a duplicate definition, you can use the Save() method
to save it with the GIF encoder, which preserves the 8-BPP color table.
>I guess the "unmodified " is what allows it. Maybe when the bitmap data is
added the "save" color table get frozen. You think?
I wouldn't presume to guess, but it appears to be the case.
>Q319061 shows how and I believe it is just what Powell does.

Code is at the bottom of this link in the panel1_Click sub at

http://www.bobpowell.net/giftransparency.htm
ok, that is exactly what I thought. Surely there must be faster
methods of transferring the image data, but I guess that sample
would work fine for small images.
>Do you know why it is always 8bpp. Other formats such as 4bpp are possible
but never seem to be saved by GDI+
The GDI+ codecs are extremely limited. Use a proper image library if
you need anything other than the most basic formats.
>Also, I found Q319061 when I was looking for the file format for a GIF file
(read via a stream) if you know where that is I'd appreciate the link.
A link to the gif specification?
http://www.w3.org/Graphics/GIF/spec-gif89a.txt

Surely you are not thinking about converting raw<->gif yourself?
Too much work. No need to reinvent the wheel.

Yes, Q319061 seems to hold all the answers we (you) were looking
for.

Regards,

Joergen Bech

Aug 21 '07 #15
>
>>Do you know why it is always 8bpp. Other formats such as 4bpp are
possible
but never seem to be saved by GDI+

The GDI+ codecs are extremely limited. Use a proper image library if
you need anything other than the most basic formats.
You don't know of a free one do you?
>
>>Also, I found Q319061 when I was looking for the file format for a GIF
file
(read via a stream) if you know where that is I'd appreciate the link.

A link to the gif specification?
http://www.w3.org/Graphics/GIF/spec-gif89a.txt
thanks
>
Surely you are not thinking about converting raw<->gif yourself?
Too much work. No need to reinvent the wheel.
No. Maybe just reading things like the Color Resolution because I don't
know what's in the file and what GDI+ did to the data.
Aug 21 '07 #16
On Tue, 21 Aug 2007 15:53:31 -0400, "\"Frank\"" <Fr***@a-znet.com>
wrote:
>>>Do you know why it is always 8bpp. Other formats such as 4bpp are
possible
but never seem to be saved by GDI+

The GDI+ codecs are extremely limited. Use a proper image library if
you need anything other than the most basic formats.

You don't know of a free one do you?
Not really. There are free or open source imaging libraries around,
but they usually add functionality not found in GDI+ rather than
completely replacing GDI+

What you want is probably something that allows you to control
the image format and perform image operations within that format
without ever going to 32-bit and back again, which GDI+ is likely
to force you to do. Something like LeadTools, which will set you back
a pretty penny.

I have yet to find a freeware imaging library that completely replaces
GDI+ - codecs, raster operations, and all.

Even something like Paint .Net does not really let you work with
8-bit images natively. You can load and save 8-bit images, but as
soon as the image goes in, it is converted to 32-bit and the image
must be converted again if saving using one of the 8-bit formats.

Not much general interest in <32-bit imaging these days :)

/Joergen Bech

Aug 22 '07 #17
I would think that for the Internet if a 4-bpp would look OK it would be
preferred to 8-bpp.

Don't you think?

">
Not much general interest in <32-bit imaging these days :)

/Joergen Bech

Aug 22 '07 #18

No, when we are dealing with low-color images in the compressed
formats (such as gif or png), it does not really matter much if the
image is stored using 16 colors or 256 colors (where the 240 colors
are unused).

As a test, I took an enormous image, reduced it to 4 colors and
saved it as a 4-bit (16MB) as well as an 8-bit (32MB) image.
I then compressed those two. The results were 1.0MB for the
4-bit version and 1.1MB for the 8-bit version.

Yes, the 8-bit version was larger, but do you really want to jump
through hoops (write a lot of code and decide on different color
depths for each image) just to save 10% or thereabouts?
I think you are optimizing before actually having tested if the
optimization is necessary.

Keep it simple. You really only need to decide between 8-bit
and lossless, 24-bit and lossy, or 24-bit and lossless. The latter
case is probably rare.

/Joergen Bech

On Wed, 22 Aug 2007 10:53:38 -0400, "\"Frank\"" <Fr***@a-znet.com>
wrote:
>I would think that for the Internet if a 4-bpp would look OK it would be
preferred to 8-bpp.

Don't you think?

">
>Not much general interest in <32-bit imaging these days :)

/Joergen Bech
Aug 22 '07 #19

"Joergen Bech @ post1.tele.dk>" <jbech<NOSPAMNO SPAMwrote in message
news:ck******** *************** *********@4ax.c om...
>
No, when we are dealing with low-color images in the compressed
formats (such as gif or png), it does not really matter much if the
image is stored using 16 colors or 256 colors (where the 240 colors
are unused).

As a test, I took an enormous image, reduced it to 4 colors and
saved it as a 4-bit (16MB) as well as an 8-bit (32MB) image.
I then compressed those two. The results were 1.0MB for the
4-bit version and 1.1MB for the 8-bit version.

Yes, the 8-bit version was larger, but do you really want to jump
through hoops (write a lot of code and decide on different color
depths for each image) just to save 10% or thereabouts?
I think you are optimizing before actually having tested if the
optimization is necessary.
I'm not doing Internet development.
It was just a random thought.

Thanks for the insight

>
Keep it simple. You really only need to decide between 8-bit
and lossless, 24-bit and lossy, or 24-bit and lossless. The latter
case is probably rare.

/Joergen Bech

On Wed, 22 Aug 2007 10:53:38 -0400, "\"Frank\"" <Fr***@a-znet.com>
wrote:
>>I would think that for the Internet if a 4-bpp would look OK it would be
preferred to 8-bpp.

Don't you think?

">
>>Not much general interest in <32-bit imaging these days :)

/Joergen Bech

Aug 22 '07 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

50
6384
by: Dan Perl | last post by:
There is something with initializing mutable class attributes that I am struggling with. I'll use an example to explain: class Father: attr1=None # this is OK attr2= # this is wrong def foo(self, data): self.attr1=data self.attr2.append(data) The initialization of attr1 is obviously OK, all instances of Father redefine it in the method foo. But the initialization of attr2 is wrong
13
2391
by: Bryan Parkoff | last post by:
I have created three classes according to my own design. First class is called CMain. It is the Top Class. Second class and third class are called CMemory and CMPU. They are the sub-classes. Two sub-classes have the relationship to communicate back and forth through this pointer. The pointer is responsible inside Top class for allocating and deallocating two sub-classes. CMemory class is responsible to allocate and deallocate memory...
23
5186
by: Fabian Müller | last post by:
Hi all, my question is as follows: If have a class X and a class Y derived from X. Constructor of X is X(param1, param2) . Constructor of Y is Y(param1, ..., param4) .
3
1676
by: G. Purby | last post by:
What is the proper way of defining a class that inherits from a base class that has no constructor with 0 arguments? The following code generates compiler error CS1501, "No overload for method 'BaseClass' takes '0' arguments". class BaseClass { public BaseClass(double x) {
10
4702
by: Joel | last post by:
Is it true that if we don't specify a default constructor for our class, then the C# compiler provides us with its own that zeroes (or assigns default values) to the data members? I wrote a no-parameter constructor for my class with an empty function body. I then instantiated an object and tried printing its values, amazingly the members were already initialized. But how is this possible if I have not included any code for doing so. The...
10
11448
by: Nathan Sokalski | last post by:
How do I create a new System.Drawing.Imaging.ColorPalette? ColorPalette does not have a constructor, and the Entries property is ReadOnly. How are we supposed to specify a palette other than the default? If there were a method to import an Array or Collection of System.Drawing.Color or something, it would be no problem, but the way it is set up right now I pretty much feel like it is useless. Any ideas? Thanks. -- Nathan Sokalski...
0
9685
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10459
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10187
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10018
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5446
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5578
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4120
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3735
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2928
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.