[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.drawing

Accepted Bug?) How does Graphics.DrawImage use ImageAttributes.SetColorMatrix matrix?

Robby

12/12/2004 12:09:00 PM


It seems a little odd to me that the matrix set in
ImageAttributes.SetColorMatrix is not being used for matrix multiplication
in Graphics.DrawImage on the pixel values.

In particular the matrix,

Dim mx As ColorMatrix = _
New ColorMatrix(New Single()() _
{New Single() {-1, 0, 0, 0, 0}, _
New Single() {0, -1, 0, 0, 0}, _
New Single() {0, 0, -1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})

almost produces a "negative" image when used with Graphics.DrawImage in an
ImageAttribute. However, this matrix clearly should not produce a negative
image as it gives a pixel of {r, g, b} a new value of {-r, -g, -b} and we
all know that the valid values are 0 to 255 so negative values are not
possible. The correct matrix to use by matrix multiplication as defined in
the Framework SDK (and mathematically with row RGB vectors) should be,

Dim mx As ColorMatrix = _
New ColorMatrix(New Single()() _
{New Single() {-1, 0, 0, 0, 0}, _
New Single() {0, -1, 0, 0, 0}, _
New Single() {0, 0, -1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {255, 255, 255, 0, 1}})

which would give the correct values of a "negative" pixel of {r, g, b} a new
value of {255-r, 255-g, 255-b}. However, this ColorMatrix maps all pixels
to {255, 255, 255}.

It seems to me that when confronted with a negative diagonal entry (ie
ColorMatrix(0,0), ColorMatrix(1,1), ... ) that the Framework is doing
something "clever" with that value instead of simply multiplying it. This
cleverness results in it mapping both starting values of 255 and 0 to a new
value of 0. This has obvious problems. Bob Powell's site offers a clever
work around that rescales the RGB values from 0 to 255 down to 1 to 255.
This brings with it a new set of problems when taking the negative image of
the negative image as colors do not match back to their originals correctly
as there is know way of knowing whether to map a 1 to 0 or to 1. Also it
seems that successive image negations noticeablely darken the image.

Anyway, I said all this simply to ask if anyone knows how to turn off this
special case of negative multiplication in Graphics.DrawImage when using
ImageAttributes.SetColorMatrix. I've searched the Framework and have come
up empty handed. Hopefully someone out there can help.

Thanks in advance

Robby


3 Answers

Robby

12/12/2004 11:27:00 PM

0


Alternatively it would be good if they just fixed 255 and 0 mapping to 0.
This seems to be an easier solution as it will not break the special case of
negative multiplication. 255 should map to 0 and 0 should map to 255.

Is there going to be a fix the new version?

Robby


"Robby" <edmund@not.my.email.com> wrote in message
news:OyauSNE4EHA.4008@TK2MSFTNGP15.phx.gbl...
>
> It seems a little odd to me that the matrix set in
> ImageAttributes.SetColorMatrix is not being used for matrix multiplication
> in Graphics.DrawImage on the pixel values.
>
> In particular the matrix,
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {0, 0, 0, 0, 1}})
>
> almost produces a "negative" image when used with Graphics.DrawImage in an
> ImageAttribute. However, this matrix clearly should not produce a
> negative image as it gives a pixel of {r, g, b} a new value of
> {-r, -g, -b} and we all know that the valid values are 0 to 255 so
> negative values are not possible. The correct matrix to use by matrix
> multiplication as defined in the Framework SDK (and mathematically with
> row RGB vectors) should be,
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {255, 255, 255, 0, 1}})
>
> which would give the correct values of a "negative" pixel of {r, g, b} a
> new value of {255-r, 255-g, 255-b}. However, this ColorMatrix maps all
> pixels to {255, 255, 255}.
>
> It seems to me that when confronted with a negative diagonal entry (ie
> ColorMatrix(0,0), ColorMatrix(1,1), ... ) that the Framework is doing
> something "clever" with that value instead of simply multiplying it. This
> cleverness results in it mapping both starting values of 255 and 0 to a
> new value of 0. This has obvious problems. Bob Powell's site offers a
> clever work around that rescales the RGB values from 0 to 255 down to 1 to
> 255. This brings with it a new set of problems when taking the negative
> image of the negative image as colors do not match back to their originals
> correctly as there is know way of knowing whether to map a 1 to 0 or to 1.
> Also it seems that successive image negations noticeablely darken the
> image.
>
> Anyway, I said all this simply to ask if anyone knows how to turn off this
> special case of negative multiplication in Graphics.DrawImage when using
> ImageAttributes.SetColorMatrix. I've searched the Framework and have come
> up empty handed. Hopefully someone out there can help.
>
> Thanks in advance
>
> Robby
>


Mick Doherty

12/31/2004 2:09:00 PM

0

I've just been playing with ColorMatrices myself. I haven't found too much
information on them but I have come up with the following theory on how I
believe they work.

ColorMatrix00 to ColorMatrix03, ColorMatrix10 to ColorMatrix13, ColorMatrix
20 to ColorMatrix23, ColorMatrix30 to ColorMatrix33, are multipliers.

128 * -1 = -128
255 * -1 = -255
1 * -1 =-1
0 * -1 = 0
negative values are subtracted from 255 and positive values are added to 0,
so:

if original r,g,b component was 128 it now becomes 255 - 128 = 128
if original r,g,b component was 255 it now becomes 255 - 255 = 0
if original r,g,b component was 1 it now becomes 255 - 1 = 254
if original r,g,b component was 0 it now becomes 0 + 0 = 0


ColorMatrix40, ColorMatrix41, ColorMatrix 42, ColorMatrix43, are used to Add
a multiple of 1 Full Intensity bit.

So if you wish to add 255 to the original value you simply add 1.0f


The following colormatrix will Invert the original bitmap, whilst preserving
the alpha.

Dim mx As ColorMatrix = _
New ColorMatrix(New Single()() _
{New Single() {-1, 0, 0, 0, 0}, _
New Single() {0, -1, 0, 0, 0}, _
New Single() {0, 0, -1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {1, 1, 1, 0, 1}})

Whilst the following Matrix will Invert all but Black, whilst preserving
Alpha.

Dim mx As ColorMatrix = _
New ColorMatrix(New Single()() _
{New Single() {-1, 0, 0, 0, 0}, _
New Single() {0, -1, 0, 0, 0}, _
New Single() {0, 0, -1, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})

--
Mick Doherty
http://dotnetrix.co.uk/no...


"Robby" <edmund@not.my.email.com> wrote in message
news:OyauSNE4EHA.4008@TK2MSFTNGP15.phx.gbl...
>
> It seems a little odd to me that the matrix set in
> ImageAttributes.SetColorMatrix is not being used for matrix multiplication
> in Graphics.DrawImage on the pixel values.
>
> In particular the matrix,
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {0, 0, 0, 0, 1}})
>
> almost produces a "negative" image when used with Graphics.DrawImage in an
> ImageAttribute. However, this matrix clearly should not produce a
> negative image as it gives a pixel of {r, g, b} a new value of
> {-r, -g, -b} and we all know that the valid values are 0 to 255 so
> negative values are not possible. The correct matrix to use by matrix
> multiplication as defined in the Framework SDK (and mathematically with
> row RGB vectors) should be,
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {255, 255, 255, 0, 1}})
>
> which would give the correct values of a "negative" pixel of {r, g, b} a
> new value of {255-r, 255-g, 255-b}. However, this ColorMatrix maps all
> pixels to {255, 255, 255}.
>
> It seems to me that when confronted with a negative diagonal entry (ie
> ColorMatrix(0,0), ColorMatrix(1,1), ... ) that the Framework is doing
> something "clever" with that value instead of simply multiplying it. This
> cleverness results in it mapping both starting values of 255 and 0 to a
> new value of 0. This has obvious problems. Bob Powell's site offers a
> clever work around that rescales the RGB values from 0 to 255 down to 1 to
> 255. This brings with it a new set of problems when taking the negative
> image of the negative image as colors do not match back to their originals
> correctly as there is know way of knowing whether to map a 1 to 0 or to 1.
> Also it seems that successive image negations noticeablely darken the
> image.
>
> Anyway, I said all this simply to ask if anyone knows how to turn off this
> special case of negative multiplication in Graphics.DrawImage when using
> ImageAttributes.SetColorMatrix. I've searched the Framework and have come
> up empty handed. Hopefully someone out there can help.
>
> Thanks in advance
>
> Robby
>


Robby

12/31/2004 11:34:00 PM

0


I think this part needs to be fix ...

> if original r,g,b component was 255 it now becomes 255 - 255 = 0
> if original r,g,b component was 0 it now becomes 0 + 0 = 0

and this part ...

> ColorMatrix40, ColorMatrix41, ColorMatrix 42, ColorMatrix43, are used to
> Add a multiple of 1 Full Intensity bit.
> So if you wish to add 255 to the original value you simply add 1.0f

The first part makes the ColorMatrix operation not "one to one" and
therefore it does not have a reverse operation. Since it is not "one to
one" and has no reverse it is not a transformation. I think it is
misleading and confusing to go through the effort of correctly defining
matrix operations in the Framework SDK and then have the matrices in the
Framework not follow the rules. Worst than that there is no way of getting
the matrices to follow the rules correctly. I feel it is a serious flaw
since you cannot really use ColorMatrix to do any real transformations.

The second part is truly weird since it shows that the ColorMatrix is using
2 separate scales for different entries. Sub-matrix (0,0) to (3,3) is on a
scale of 0 to 255 while the lower row and outer column are on a scale of 0
to 1 mapping to 0 to 255. This completely erases any hope of using
ColorMatrix for even the most basic transformation. The scale needs to be
the same throughout the entire matrix.

I don't think that MS decided that GDI+ colour developers would be too dumb
to use a matrix and so really did not bother implementing them correctly. I
say that because the other matrices in the GDI+ seem to work correctly.
This leads me to believe that ColorMatrix for ImageAttributes.SetColorMatrix
in Graphics.DrawImage is bugged.


Does anyone at MS have a comment?

Robby


"Mick Doherty"
<EXCHANGE#WITH@AND.REMOVE.SQUAREBRACKETS.[mdaudi100#ntlworld.com]> wrote in
message news:%23H0JFJ07EHA.1452@TK2MSFTNGP11.phx.gbl...
> I've just been playing with ColorMatrices myself. I haven't found too much
> information on them but I have come up with the following theory on how I
> believe they work.
>
> ColorMatrix00 to ColorMatrix03, ColorMatrix10 to ColorMatrix13,
> ColorMatrix 20 to ColorMatrix23, ColorMatrix30 to ColorMatrix33, are
> multipliers.
>
> 128 * -1 = -128
> 255 * -1 = -255
> 1 * -1 =-1
> 0 * -1 = 0
> negative values are subtracted from 255 and positive values are added to
> 0, so:
>
> if original r,g,b component was 128 it now becomes 255 - 128 = 128
> if original r,g,b component was 255 it now becomes 255 - 255 = 0
> if original r,g,b component was 1 it now becomes 255 - 1 = 254
> if original r,g,b component was 0 it now becomes 0 + 0 = 0
>
>
> ColorMatrix40, ColorMatrix41, ColorMatrix 42, ColorMatrix43, are used to
> Add a multiple of 1 Full Intensity bit.
>
> So if you wish to add 255 to the original value you simply add 1.0f
>
>
> The following colormatrix will Invert the original bitmap, whilst
> preserving the alpha.
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {1, 1, 1, 0, 1}})
>
> Whilst the following Matrix will Invert all but Black, whilst preserving
> Alpha.
>
> Dim mx As ColorMatrix = _
> New ColorMatrix(New Single()() _
> {New Single() {-1, 0, 0, 0, 0}, _
> New Single() {0, -1, 0, 0, 0}, _
> New Single() {0, 0, -1, 0, 0}, _
> New Single() {0, 0, 0, 1, 0}, _
> New Single() {0, 0, 0, 0, 1}})
>
> --
> Mick Doherty
> http://dotnetrix.co.uk/no...
>
>
> "Robby" <edmund@not.my.email.com> wrote in message
> news:OyauSNE4EHA.4008@TK2MSFTNGP15.phx.gbl...
>>
>> It seems a little odd to me that the matrix set in
>> ImageAttributes.SetColorMatrix is not being used for matrix
>> multiplication in Graphics.DrawImage on the pixel values.
>>
>> In particular the matrix,
>>
>> Dim mx As ColorMatrix = _
>> New ColorMatrix(New Single()() _
>> {New Single() {-1, 0, 0, 0, 0}, _
>> New Single() {0, -1, 0, 0, 0}, _
>> New Single() {0, 0, -1, 0, 0}, _
>> New Single() {0, 0, 0, 1, 0}, _
>> New Single() {0, 0, 0, 0, 1}})
>>
>> almost produces a "negative" image when used with Graphics.DrawImage in
>> an ImageAttribute. However, this matrix clearly should not produce a
>> negative image as it gives a pixel of {r, g, b} a new value of
>> {-r, -g, -b} and we all know that the valid values are 0 to 255 so
>> negative values are not possible. The correct matrix to use by matrix
>> multiplication as defined in the Framework SDK (and mathematically with
>> row RGB vectors) should be,
>>
>> Dim mx As ColorMatrix = _
>> New ColorMatrix(New Single()() _
>> {New Single() {-1, 0, 0, 0, 0}, _
>> New Single() {0, -1, 0, 0, 0}, _
>> New Single() {0, 0, -1, 0, 0}, _
>> New Single() {0, 0, 0, 1, 0}, _
>> New Single() {255, 255, 255, 0, 1}})
>>
>> which would give the correct values of a "negative" pixel of {r, g, b} a
>> new value of {255-r, 255-g, 255-b}. However, this ColorMatrix maps all
>> pixels to {255, 255, 255}.
>>
>> It seems to me that when confronted with a negative diagonal entry (ie
>> ColorMatrix(0,0), ColorMatrix(1,1), ... ) that the Framework is doing
>> something "clever" with that value instead of simply multiplying it.
>> This cleverness results in it mapping both starting values of 255 and 0
>> to a new value of 0. This has obvious problems. Bob Powell's site offers
>> a clever work around that rescales the RGB values from 0 to 255 down to 1
>> to 255. This brings with it a new set of problems when taking the
>> negative image of the negative image as colors do not match back to their
>> originals correctly as there is know way of knowing whether to map a 1 to
>> 0 or to 1. Also it seems that successive image negations noticeablely
>> darken the image.
>>
>> Anyway, I said all this simply to ask if anyone knows how to turn off
>> this special case of negative multiplication in Graphics.DrawImage when
>> using ImageAttributes.SetColorMatrix. I've searched the Framework and
>> have come up empty handed. Hopefully someone out there can help.
>>
>> Thanks in advance
>>
>> Robby
>>
>
>