The principle of changing the brightness of an image is easy.
here is the pseudo to add 20 to the brightness...
Code:
For Each Pixel
Get Pixel Color RGB
''''Add 20 to each colour in the pixel
Pixel.R = Pixel.R + 20
Pixel.G = Pixel.G + 20
Pixel.B = Pixel.B + 20
''''Clip the values so they go no higher than 255
''''and no lower than 0
If Pixel.R > 255 Then Pixel.R = 255
If Pixel.G > 255 Then Pixel.G = 255
If Pixel.B > 255 Then Pixel.B = 255
If Pixel.R < 0 Then Pixel.R = 0
If Pixel.G < 0 Then Pixel.G = 0
If Pixel.B < 0 Then Pixel.B = 0
Set New Pixel Color
Next Pixel
I have modified a blur image function that i posted earlier to change the brightness and have included the demo project in this post (see screenie). If you dont need to use GDI+ then feel free to use it.
If you have any questions please ask.
Thanks for your reply.
While your code is very good I would like to find a GDI+ specif answer.
There are several ways to do what I want in GDI+ but I cant find any information or examples on it, only just enough to know that it is possible.
If anyone has any examples using matrices or applying effects then I would appreciate any info you can pass along.
Having said that I cant just sit here twiddling my thumbs so I gave your idea a go just to see if it would work.
Here is my code.
Public Function Lighten()
Dim retval As Long
Dim R As RECTL
Dim BMData As BitmapData
Dim bytecount As Long
Dim Pixels() As Byte
Dim Y As Integer
Dim X As Integer
'setup values
bytecount = BMData.Width * BMData.Height
ReDim Pixels(bytecount - 1)
'copy data into our array for manipulation
CopyMemory Pixels(0), BMData.Scan0Ptr, bytecount
'change values
For Y = 0 To ImageHeight - 1
For X = 0 To ImageWidth - 1
Pixels(X + Y) = Pixels(X + Y) - 20
If Pixels(X + Y) < 0 Then Pixels(X + Y) = 0
Next
Next
'copy memory back
CopyMemory BMData.Scan0Ptr, Pixels(0), bytecount
retval = GdipBitmapUnlockBits(m_Bitmap, BMData)
End Function
Unfortunatly it doesnt work
It crashes on the 1st Copy memory line where Im trying to copy the pixel data into my byte array.
I havent used CopyMemory very often so if anyone can obviously see what im doing wrong then pls post a fix.
ok, i cant debug that code as i really need the project in front of me... but i am going to point you towards a GDI+ example, it does not include brightness but it might give you some ideas. Scale, Rotate, Skew and Transform Images using GDI+
That's a good start using LockBits.. but you have to remember that 24 bit BMP data is aligned on 4 byte boundries. So use a 2D array with the padded width and just access pixels up to the actual width. Instead of using RtlMoveMemory, you can pass VarPtr(my2DArray(0,0)) and use LockBits with these flags: ImageLockModeUserInputBuf Or ImageLockModeRead
Then your 2D array will be filled with the data.
One you've finished manipulating the pixels call LockBits again with ImageLockModeWrite Or ImageLockModeUserInputBuf to write the array.
Btw, if you'll look at my gdiplus3.zip in the code library (specifically modQuantize.bas) you'll see this method in action. I use a 1D array, which is cumbersome (but I was trying to speed things along), which is why I suggest the 2D array.
Thank you for your replies.
I have managed to succesfully apply a colour shift matrix using the GDI+ ImageAttributes functions and alter the brightness of my image.
I have included the function below for anyone else who might be interested.
Public Function AlterBrightness(ByVal howmuch As Single)
'applies a colour matrix to the image
'The ShiftInBrightness range is from -1 (complete blackness) to 1 (complete white)
'so to brighten an image 20% pass a value of 0.2, to darken it by 20% pass a value of -0.2
Dim retval As Long
Dim hAttributes As Long
Dim cmBrightness As ColorMatrix
Dim cmGrey As ColorMatrix
'create an ImageAttribute which we will apply to our image
retval = GdipCreateImageAttributes(hAttributes)
'assign our matrix to the ImageAttribute
retval = GdipSetImageAttributesColorMatrix(hAttributes, ColorAdjustTypeDefault, True, cmBrightness, cmGrey, ColorMatrixFlagsDefault)
'overwrite our existing image rather than blend with it
retval = GdipSetCompositingMode(m_Graphic, CompositingModeSourceOver)
'the translation algorithem to use (InterpolationModeHighQualityBicubic produces the highest quality)
'not sure if this is necessary since documentation says it is used "when images are scaled or rotated"
retval = GdipSetInterpolationMode(m_Graphic, InterpolationModeHighQualityBicubic)
'Indicate that pixel centers have coordinates that are half way between integer values.
retval = GdipSetPixelOffsetMode(m_Graphic, PixelOffsetModeHighQuality)
'draw the image onto itself applying the matrix as it does so
retval = GdipDrawImageRectRectI(m_Graphic, m_Bitmap, 0, 0, ImageWidth, ImageHeight, 0, 0, ImageWidth, ImageHeight, UnitPixel, hAttributes)
'clean up
retval = GdipDisposeImageAttributes(hAttributes)
The matrix to alter the contrast is supposed to be as follows
With cmContrast
.m(0, 0) = howmuch
.m(1, 1) = howmuch
.m(2, 2) = howmuch
.m(3, 3) = 1
.m(4, 4) = 1
End With
To halve the contrast you would set howmuch to be 0.5 and to double it you would use 2.
This does alter the image nicely if you use a value below 1 but i have found that taking it even fractionally above 1.0 causes my pictures to be ruined with globs of colour smeared all across them.
Perhaps it would be worthwhile trying other interpolation modes or something but all I needed was the brightness so im going to be stopping here.
If anyone continues this work then pls post your results.
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET. subscribe