|

Introduction
This article discusses color operations on digital images, using the new ColorMatrix class provided by GDI+. The ColorMatrix is a welcome addition to the GDI library, especially with the increase in demand of digital imaging applications, as more and more consumer products are made available. This class, as well as many other new GDI classes, provide more control to the developer and reduce dependence on 3rd party applications such as LEAD tools, and others. Some basic knowledge of matrix operations (multiplication, addition, etc), the RGBA colorspace and GDI+ is assumed.
Background
ColorMatrix operations are performed in the RGBA colorspace (red, green, blue, alpha). A ColorMatrix consists of a 5x5 matrix, with color values normalized to 1 for full intensity (255 -> 1.0). You might expect the matrix to be 4x4 ( [R, G, B, A] ), which would be sufficient if we only needed to perform linear transformations (multiplication: scaling, rotation, etc). However, one of the most frequent color manipulations, color adjustment, requires adding color values. This is a non-linear operation, referred to as a translation. Adding a 5th element to the color vector ( [R, G, B, A, w] ) combines these two operations, linear and non-linear, into a single operation called an affine transformation. The 5th element of the color vector is simply a dummy element, always with a value of 1, which only serves to allow a translation (addition) of the color vector.
The example below scales the color vector [255, 128, 102, 255] by .5 and then adds a value of 26 to the R, G and B components, leaving the A component at full intensity. Remember that the component values are normalized, with full intensity, 255, equal to 1.0 (values have been rounded to the nearest tenth). Also notice the addition of the 5th element to the color vector, which is simply ignored in the resultant color vector.
This takes the color and transforms it to .
Now that we've covered the basic principle of the ColorMatrix and it's operations on color vectors, we can start exploring some practical uses.
Applying the code
Applying a ColorMatrix to an image is quite simple. You must first associate a ColorMatrix object with an ImageAttributes object. Then you simply pass the ImageAttributes object as a parameter to the Graphics.DrawImage method.
Color adjustment is one of the more common color operations applied to digital images. The code to do this might look as follows: Public Function translate(ByVal img As Image, ByVal red As Single, _
ByVal green As Single, ByVal blue As Single, _
Optional ByVal alpha As Single = 0) As Boolean
Dim sr, sg, sb, sa As Single
sr = red / 255
sg = green / 255
sb = blue / 255
sa = alpha / 255
dim 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() {sr, sg, sb, sa, 1}})
Return draw_adjusted_image(img, cm)
End Function
Private Function draw_adjusted_image(ByVal img As Image, _
ByVal cm As ColorMatrix) As Boolean
Try
Dim bmp As New Bitmap(img)
Dim imgattr As New ImageAttributes()
Dim rc As New Rectangle(0, 0, img.Width, img.Height)
Dim g As Graphics = Graphics.FromImage(img)
imgattr.SetColorMatrix(cm)
g.DrawImage(bmp, rc, 0, 0, img.Width, img.Height, _
GraphicsUnit.Pixel, imgattr)
g.Dispose()
Return True
Catch
Return False
End Try
End Function
Conversion to grayscale is another common conversion. Grayscale values are determined by calculating the luminosity of a color, which is a weighted average of the R, G and B color components. The average is weighted according to the sensitivity of the human eye to each color component. The weights used here are as given by the NTSC (North America Television Standards Committee) and are widely accepted. Public Function grayscale(ByVal img As Image) As Boolean
Dim cm As ColorMatrix = New ColorMatrix(New Single()() _
{New Single() {0.299, 0.299, 0.299, 0, 0}, _
New Single() {0.587, 0.587, 0.587, 0, 0}, _
New Single() {0.114, 0.114, 0.114, 0, 0}, _
New Single() {0, 0, 0, 1, 0}, _
New Single() {0, 0, 0, 0, 1}})
Return draw_adjusted_image(img, cm)
End Function
The code below creates a digital negative: Public Function negative(ByVal img As Image) As Boolean
Dim cm 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}})
Return draw_adjusted_image(img, cm)
End Function
Color channel separations, alpha transparency adjustment, image toning (Sepia, etc) are just a few more common operations that can be easily performed with a ColorMatrix.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 54 (Total in Forum: 54) (Refresh) | FirstPrevNext |
|
|
 |
|
|
Hi, all.
Does anyone have a ColorMatrix to make an image use only 2 colors (Black and White)? The effect should be similar to that of a fax print out.
Possibly, passing in a "quality" (threshold) parameter.
Let's say the average ((r + g + b) /3) of the color components is lower or equal to 128 *, the result will be 0 for all the components.
Else, it would be 255 (1, in the ColorMatrix "language").
* 128 (0.5 is my standard threshold).
Maybe, it can be done in two passages, first converting the image to gray and then applying a "threshold filter", to call it so?
Bob Powell (Converting an RGB image to 1 bit-per-pixel monochrome) succeeded in, but: 1. He uses unmanaged APIs. 2. He uses InterOps. 3. He does the thing one pixel at a time...
Bob is really an experienced developer, buy this "naive" solution is totally unacceptable for me.
Is there anyone that can do the same by using a ColorMatrix? Or an ImageAttributes? Or a combination of the two?
modified on Monday, May 26, 2008 7:22 AM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Sorry, but I had to reply myself, since I did find a "not too bad" solution, and it might be that someone of you finds it useful for their needs.
Well, I ended up with a two steps solution. I'm still waiting to find a single ColorMatrix that could do that on the fly...
Also, I noticed that some Images don't pruduce a TRUE B/W, but there's still some color bleeding. This happens with some PNG Images.
I think it's due to a "dirty" Alpha Channel, but still can't help.
Maybe, a solution could be calling the ImageBlackAndWhite Method twice, or to put a For cicle inside it to repeat the two steps twice.
' The Methods I use to do the Conversions:
Friend Sub ImageBlackAndWhite(ByVal img As Image, _ ByVal Threshold As Int32) ' This Method returns the Image in pure Black & White Colors. ' Very much like a Fax Print out. ' Two Steps are required, and the Order is meaningful. ' Adjust the Threshold Value. If Threshold < 0 Then Threshold = 0 If Threshold > 100 Then Threshold = 100 ' This is a two Step Operation: ' First Step: ' Convert the Image to GrayScale. ImageGrayScale(img) ' Second Step: ' Set a Threshold to the Image. ImageThreshold(img, Threshold) End Sub
Friend Sub ImageGrayScale(ByVal img As Image) ' This Method converts an Image to GrayScale. ' Create the Color Matrix. '' SimpleAverage GrayScale Matrix. 'Dim cm As New ColorMatrix(New Single()() { _ ' New Single() {0.333F, 0.333F, 0.333F, 0, 0}, _ ' New Single() {0.333F, 0.333F, 0.333F, 0, 0}, _ ' New Single() {0.333F, 0.333F, 0.333F, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) '' WeightAverage GrayScale Matrix. 'Dim cm As New ColorMatrix(New Single()() { _ ' New Single() {0.333F, 0.333F, 0.333F, 0, 0}, _ ' New Single() {0.444F, 0.444F, 0.444F, 0, 0}, _ ' New Single() {0.222F, 0.222F, 0.222F, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) '' Bob Powell's GrayScale Matrix. 'Dim cm As ColorMatrix = New ColorMatrix(New Single()() { _ ' New Single() {0.5, 0.5, 0.5, 0, 0}, _ ' New Single() {0.5, 0.5, 0.5, 0, 0}, _ ' New Single() {0.5, 0.5, 0.5, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) '' Gilles Khouzam's Colour corrected Shear GrayScale Matrix. 'Dim cm As ColorMatrix = New ColorMatrix(New Single()() { _ ' New Single() {0.3, 0.3, 0.3, 0, 0}, _ ' New Single() {0.59, 0.59, 0.59, 0, 0}, _ ' New Single() {0.11, 0.11, 0.11, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) '' Luminance Vector GrayScale Matrix. '' This is the one Microsoft prefers. 'Dim cm As New ColorMatrix(New Single()() { _ ' New Single() {0.3086F, 0.3086F, 0.3086F, 0, 0}, _ ' New Single() {0.6094F, 0.6094F, 0.6094F, 0, 0}, _ ' New Single() {0.082F, 0.082F, 0.082F, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) '' NtscPal (CCIR Rec. 604 standard) GrayScale Matrix. 'Dim cm As New ColorMatrix(New Single()() { _ ' New Single() {0.299F, 0.299F, 0.299F, 0, 0}, _ ' New Single() {0.587F, 0.587F, 0.587F, 0, 0}, _ ' New Single() {0.114F, 0.114F, 0.114F, 0, 0}, _ ' New Single() {0, 0, 0, 1, 0}, _ ' New Single() {0, 0, 0, 0, 1}}) ' CCIR Rec. 709 standard GrayScale Matrix. ' This one is the most used. Dim cm As New ColorMatrix(New Single()() { _ New Single() {0.213F, 0.213F, 0.213F, 0, 0}, _ New Single() {0.715F, 0.715F, 0.715F, 0, 0}, _ New Single() {0.072F, 0.072F, 0.072F, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) ' Apply the Matrix to the Image. DrawImage(img, cm) End Sub
Friend Sub ImageThreshold(ByVal img As Image, _ ByVal Threshold As Int32) ' This Method sets an Image Threshold. ' Adjust Threshold Value. If Threshold < 0 Then Threshold = 0 If Threshold > 100 Then Threshold = 100 ' 0.01F * x is faster than x / 100 Dim tsh As Single = 0.01F * Threshold ' Create an ImageAttributes Object, and set its Bitmap Threshold. Dim ia As New ImageAttributes ia.SetThreshold(tsh, ColorAdjustType.Bitmap) ' Apply the ImageAttributes to the Image. DrawImage(img, ia) End Sub
' I also use these Overloads:
Private Overloads Sub DrawImage(ByVal img As Image, _ ByVal cm As ColorMatrix) ' Draw an Image with a specified ColorMatrix Object. Try ' Create a Copy of the Source Image. Dim bmp As New Bitmap(img) Dim ia As New ImageAttributes Dim rect As New Rectangle(0, 0, img.Width, img.Height) Using gr As Graphics = Graphics.FromImage(img) ' Associate the ColorMatrix Object with an ImageAttributes ' Object. ia.SetColorMatrix(cm) ' Draw the Copy of the Source Image back over the Original ' Image, applying the ColorMatrix. gr.DrawImage(bmp, rect, 0, 0, img.Width, img.Height, _ GraphicsUnit.Pixel, ia) End Using Catch ' Eat the Exception. End Try End Sub Private Overloads Sub DrawImage(ByVal img As Image, _ ByVal ia As ImageAttributes) ' Draw an Image with a specified ImageAttributes Object. Try ' Create a Copy of the Source Image. Dim bmp As New Bitmap(img) Dim rect As New Rectangle(0, 0, img.Width, img.Height) Using gr As Graphics = Graphics.FromImage(img) ' Draw the Copy of the Source Image back over the Original ' Image, applying the ImageAttributes. gr.DrawImage(bmp, rect, 0, 0, img.Width, img.Height, _ GraphicsUnit.Pixel, ia) End Using Catch ' Eat the Exception. End Try End Sub
' Somewhere in the Form I call these Instructions and do the Trick:
' Load the Image from the original one, which is stored in PictureBox1. PictureBox7.Image = CType(PictureBox1.Image.Clone, Image) ' Apply the Transformation with a Thresold of 50%. .ImageBlackAndWhite(PictureBox7.Image, 50)
<div class="ForumMod">modified on Tuesday, May 27, 2008 7:04 AM</div>
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I know your article is quite old but it seems most relevant to what I am trying to do. I have been searching for how to write an image in Lab format instead of RGB, I have converted the RGB values into a decimal array (decimal for precision) but now I just dont know what to do with them - how do I write them back to a file in the format of Lab ?
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
help,Michael. How to do softlight on an image? What are the Values to pass for the matrix ? Is there some releated algorithms to do on the pixel?
Any help is appreciated, Thank you!
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Hi Michael
I know it's a bit long since you have done this article but I am having a problem saving the adjusted image.
I display the image and a copy. I adjust the copy using a matrix, using a copy of the source. It shows great on the screen but I am having problems actually saving the image with the matrix applied. All it does is save the copy without the matrix values applied.
This displays the source image
Private Function draw_source_image(ByVal g As Graphics) As Boolean
Try Dim bmp As New Bitmap(sourceImage, 256, 256) ' draw the source image Dim rc As New Rectangle(150, 50, sourceImage.Width, sourceImage.Height)
g.DrawImage(bmp, rc, 0, 0, sourceImage.Width, sourceImage.Height, _ GraphicsUnit.Pixel) Return True Catch Return False End Try
End Function
This displays the adjusted image
Private Function draw_adjusted_image(ByVal cm As ColorMatrix, ByVal g As Graphics) As Boolean
Try adjustedImage = New Bitmap(sourceImage, 256, 256) ' create a copy of the source image Dim imgattr As New ImageAttributes() Dim rc As New Rectangle(450, 50, sourceImage.Width, sourceImage.Height)
' associate the ColorMatrix object with an ImageAttributes object imgattr.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Default)
'applying the ColorMatrix g.DrawImage(adjustedImage, rc, 0, 0, sourceImage.Width, sourceImage.Height, _ GraphicsUnit.Pixel, imgattr)
Return True Catch Return False End Try
End Function
This saves the adjusted image to disc. I'm not too worried about the size yet as I can adjust that before the save.
Private Sub saveImage() 'here we save the image to file Dim mDiag As New SaveFileDialog
mDiag.Filter = "Bitmap Image|*.bmp" mDiag.ShowDialog() adjustedImage.Save(mDiag.FileName, ImageFormat.Bmp)
End Sub
I just want to save as a bitmap so that I can later compress it to DXT5 if necessary
Many thanks
Regards
Carl
-- modified at 12:56 Monday 12th March, 2007
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Hey there,
I did some head-scratching on this one and I've come with this:
All values in row 0 are based on the red component of the pixel to which they are applied. Likewise, all values in rows 1, 2 and 3 are based on the green, blue and alpha components of the pixel consecutively.
The values in column 0 apply to the amount of red that will be placed in a given pixel. Similarly, columns 1, 2 and 3 are applied to the green, blue and alpha components.
So, for example, if I set 00, 11, 22 and 33 to 1.0, I'll get a regular picture, because I'm specifying regular amounts of each component based on only that component.
But if I were to set 01 to 0.5 then I would be adding 0.5 times the green value of each pixel to the resulting colors red component. And so forth...
|
| Sign In·View Thread·PermaLink | 2.00/5 (3 votes) |
|
|
|
 |
|
|
I use the following method for coloring an image. My source image is a black font with a transparent background. I just want to color that graphical font. This font is not absolutely black it contains grayscales so ColorMap is not the right option.
private Bitmap ColorBitmap(Bitmap _b, Color _color) { Bitmap bmp = new Bitmap(_b.Width, _b.Height); Graphics g = Graphics.FromImage(bmp);
float cr = _color.R / 255; float cg = _color.G / 255; float cb = _color.B / 255; float ca = _color.A / 255; float[][] colorMatrixElements = { new float[] {1, 0, 0, 0, 0}, new float[] {0, 1, 0, 0, 0}, new float[] {0, 0, 1, 0, 0}, new float[] {0, 0, 0, 1, 0}, new float[] {cr, cg, cb, ca, 1}}; ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements); ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
Rectangle rectangle = new Rectangle(0, 0, _b.Width, _b.Height);
g.DrawImage(_b, rectangle, 0, 0, _b.Width, _b.Height, GraphicsUnit.Pixel, imageAttributes); return bmp; }
I must admit that I don´t understand the concepts of the ColorMatrix. Is anybody able to modify my method in a way that I am able to color a grayscale image into any color ?
Best Regards, Kevin
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Try using a matrix that combines grayscaling with the color component addition. Here goes one:
// The grayscale factors used here come from the CCIR Rec. 709 standard. float[][] colorMatrixElements = { new float[] { 0.213f, 0.213f, 0.213f, 0, 0 }, new float[] { 0.715f, 0.715f, 0.715f, 0, 0 }, new float[] { 0.072f, 0.072f, 0.072f, 0, 0 }, new float[] { 0, 0, 0, 1, 0 }, new float[] { cr, cg, cb, ca, 1 }};
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Nice article Michael.. It helped me a lot.. Is it possible to do sharpness and blur operation on the image using the Colormatrix. If so what are all the values we have to pass for the matrix elements..
Any help is appreciated.. Thanks in advance. sing
-- modified at 9:36 Friday 7th July, 2006
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
I think ColorMatrix can't sharp and blur image. ColorMatrix only changes every pixel, doesn't consider the relation of pixels, while sharp and blur must consider neighboring pixels.
It's easy to blur image, create a 3*3 matrix, calculate every pixel by matrix and neighboring pixel, for example, matrix is 0.05 0.05 0.05 0.05 0.60 0.05 0.05 0.05 0.05 pixels' gray value are 100 110 120 130 140 160 170 180 190 after blur, the center pixel's gray value is not 140, it's (100+110+120+130+160+170+180+190)*0.05+140*0.6=145.
It's easy to apply this method to RGB color space.
I don't how to sharp an image.
-- modified at 5:48 Thursday 20th July, 2006
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
There seems to be a bug in the .net2.0 printing support while using imageattributes.
I had been trying to print a jpeg image with an alpha adjust in the colormatrix. In a print preview dialog it works perfectly, however when it got to the stage of printing I was getting an outofmemory exception.
I figured it out eventually after I had tried using a png with a transparent background. The format of the image has to be 32bppARGB or changed to it, you can do this by creating a new bitmap with the 32bppARGB format that is the same size as the original and draw the original in that, the code I used is below.
Dim newImage As System.Drawing.Image = image.fromfile("c:\sample.jpg") Dim bm As New Bitmap(newImage.Width, newImage.Height, imaging.PixelFormat.Format32bppArgb)
Dim g As Graphics = Graphics.FromImage(bm) g.DrawImage(newImage, 0, 0, newImage.Width, newImage.Height) g.dispose() newimage.dispose()
bm now holds an image that can be printed using a colormatrix. This does not affect a png with a transparent background.
-- modified at 7:26 Wednesday 10th May, 2006
ok I've just found out something even better, the bug only seems to affect loading an image in the system.drawing.image class. If you use the system.drawing.bitmap class to load your image, printing works perfectly even if you do a conversion to the system.drawing.image class! I can only assume that the bitmap class defaults to the 32bppArgb format, where as the image class defaults to the files colour format.
Obviously if your using a third party class then the first method may still be appropriate as you have no control on how pictures are loaded.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
This class can be used to convert bitmaps (as well as color objects) to grayscale using several semi-standard formulas.
I had to remove the Xml documentation since it was interfering with the message format, but it should be fairly straightforward to figure out.
<code> Dim oGray As New OpenBook.Graphics.Colors.Grayscale _newImage = oGray.ConvertBitmapToGrayscale(_oldImage, OpenBook.Graphics.Colors.Grayscale.Formula.CCIRRec709) </code>
You will have to replace [OpenBook] with something else. It's simply the way I've organized the namespaces for myself.
Thanks to the original author of this tutorial on the help with ColorMatrix. It makes an enormous performance difference (even if I wish it was a bit quicker still).
Kevin Townsend
<code> Imports System.Drawing Imports System.Drawing.Imaging
Namespace Graphics.Colors
Public Class Grayscale
Public Enum Formula SimpleAverage = 0 ' Least accurate WeightAverage = 1 NtscPal = 2 ' CCIR Recommendation 601-1 (Used in Ntsc/Pal Standards) CCIRRec709 = 3 ' CCIR Recommendation 709 End Enum
Public Function ConvertRgbToGrayscale(ByVal sourceColor As Drawing.Color, Optional ByVal formula As Formula = Formula.CCIRRec709) Dim newColor As New Drawing.Color Dim a1, r1, g1, b1 As Int16 Dim a2, r2, g2, b2 As Int16
' Get source color ARGB attributes a1 = Convert.ToInt16(sourceColor.A) r1 = Convert.ToInt16(sourceColor.R) g1 = Convert.ToInt16(sourceColor.G) b1 = Convert.ToInt16(sourceColor.B)
' Calculate changes depending on foruma selected Select Case formula Case formula.SimpleAverage a2 = a1 r2 = Convert.ToInt16((r1 + g1 + b1) / 3) g2 = Convert.ToInt16((r1 + g1 + b1) / 3) b2 = Convert.ToInt16((r1 + g1 + b1) / 3) Case formula.WeightAverage a2 = a1 r2 = Convert.ToInt16((3 * r1) + (4 * b1) + (2 * g1) / 9) g2 = Convert.ToInt16((3 * r1) + (4 * b1) + (2 * g1) / 9) b2 = Convert.ToInt16((3 * r1) + (4 * b1) + (2 * g1) / 9) Case formula.NtscPal a2 = a1 r2 = Convert.ToInt16((0.299 * r1) + (0.587 * g1) + (0.114 * b1)) g2 = Convert.ToInt16((0.299 * r1) + (0.587 * g1) + (0.114 * b1)) b2 = Convert.ToInt16((0.299 * r1) + (0.587 * g1) + (0.114 * b1)) Case formula.CCIRRec709 a2 = a1 r2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) g2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) b2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) Case Else ' Use CCIR Rec 709 as default a2 = a1 r2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) g2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) b2 = Convert.ToInt16((0.2125 * r1) + (0.7154 * g1) + (0.0721 * b1)) End Select
' Check limits If r2 > 255 Then r2 = 255 If g2 > 255 Then g2 = 255 If b2 > 255 Then b2 = 255 If r2 < 0 Then r2 = 0 If g2 < 0 Then g2 = 0 If b2 < 0 Then b2 = 0
' Set newColor newColor = Drawing.Color.FromArgb(a2, r2, g2, b2)
' Return Return newColor End Function
Public Function ConvertBitmapToGrayscale(ByVal sourceImage As Bitmap, Optional ByVal formula As Formula = Formula.CCIRRec709) As Bitmap Dim output As Bitmap = New Bitmap(sourceImage.Width, sourceImage.Height) Dim rect As New Rectangle(0, 0, sourceImage.Width, sourceImage.Height) Dim cm As ColorMatrix Dim ia As New ImageAttributes ' Assign sourceBitmap to a new graphics object Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(output)
' Apply selected grayscale formula Select Case formula Case Colors.Grayscale.Formula.CCIRRec709 cm = New ColorMatrix(New Single()() _ {New Single() {0.213, 0.213, 0.213, 0, 0}, _ New Single() {0.715, 0.715, 0.715, 0, 0}, _ New Single() {0.072, 0.072, 0.072, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) Case Colors.Grayscale.Formula.NtscPal cm = New ColorMatrix(New Single()() _ {New Single() {0.299, 0.299, 0.299, 0, 0}, _ New Single() {0.587, 0.587, 0.587, 0, 0}, _ New Single() {0.114, 0.114, 0.114, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) Case Colors.Grayscale.Formula.SimpleAverage cm = New ColorMatrix(New Single()() _ {New Single() {0.333, 0.333, 0.333, 0, 0}, _ New Single() {0.333, 0.333, 0.333, 0, 0}, _ New Single() {0.333, 0.333, 0.333, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) Case Colors.Grayscale.Formula.WeightAverage cm = New ColorMatrix(New Single()() _ {New Single() {0.333, 0.333, 0.333, 0, 0}, _ New Single() {0.444, 0.444, 0.444, 0, 0}, _ New Single() {0.222, 0.222, 0.222, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) Case Else ' Use CCIR Rec. 709 as catch all cm = New ColorMatrix(New Single()() _ {New Single() {0.213, 0.213, 0.213, 0, 0}, _ New Single() {0.715, 0.715, 0.715, 0, 0}, _ New Single() {0.072, 0.072, 0.072, 0, 0}, _ New Single() {0, 0, 0, 1, 0}, _ New Single() {0, 0, 0, 0, 1}}) End Select
' Set color matrix ia.SetColorMatrix(cm)
' Render new bitmap image g.DrawImage(sourceImage, rect, 0, 0, sourceImage.Width, sourceImage.Height, GraphicsUnit.Pixel, ia)
' Return converted image Return output End Function
End Class
End Namespace
</code>
|
| Sign In·View Thread·PermaLink | 4.00/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
I noticed this on GIF pictures. So, I decided to promote the image, if it isn't in the Format32bppARGB Pixel Format, to this Pixel Format, and it worked just fine.
That's the code I use:
Public Shared Function PictureConvertToRGB(ByVal bmp As Bitmap) As Bitmap Dim img As New Bitmap(bmp.Width, bmp.Height, _ Imaging.PixelFormat.Format32bppArgb) img.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution) Using gr As Graphics = Graphics.FromImage(img) gr.DrawImageUnscaled(bmp, 0, 0) End Using Return img End Function
Give it a trial: it will surely work for you, too.
<div class="ForumMod">modified on Monday, May 26, 2008 7:38 AM</div>
|
| Sign In·View Thread· | | | | | |