from times to times someone asks about creating monochrome images, that, in most of the cases will be used to be sent by fax.
unfortunately, gdi+ does not offer full support to 1bpp indexed images (monochrome bitmaps).
but with the help of anatoliy mogylevets and mike gagnon, i could find that the good and old gdi (not gdiplus) provides some functions (copyimage and loadimage) to do that in a flash. so, we've agreed to add this important feature to the library, as a new method added to the image and bitmap classes: getmonochrome().
steps to get the monochrome 1bpp version of any image using the gdi+x classes
- load image to gdiplus
- call the image.getmonochrome to obtain a new object that will contain the 1bpp image
- save normally as bmp
important:
all samples below use the new gdiplus-x library, that is still in alpha version, but is already stable and reliable to do the majority of gdi+ tasks. download the latest stable release from codeplex:
http://www.codeplex.com/wiki/view.aspx?projectname=vfpx&title=gdiplusx
here's a sample code:
do locfile("system.app")
with _screen.system.drawing
* create a bitmap object based on a bmp file.
local looriginalbmp as xfcbitmap
looriginalbmp = .bitmap.new(getpict())
local lomonochrbmp as xfcbitmap
lomonochrbmp = looriginalbmp.getmonochrome()
* save the created monochromatic bmp
lomonochrbmp.save("c:\monochromatic.bmp", .imaging.imageformat.bmp)
endwith
return
and here are the results for two images:
the first picture seems nice, doesn't it?
but the vfpx logo did not appear in the monochrome image. that happens because the orange background from the text is dark, and gdi converts it to black.
but using a little trick we can fix that, by converting the image to a brighter greyscale before converting to monochrome. it's not in the scope of this short article to explain how to do that, because i already came into this deply in two articles published in utmag, special effects on images with new gdiplus-x classes - part 1 and special effects on images with new gdiplus-x classes - part 2.
to convert to greyscale, we can use a color matrix that will convert each pixel to the average between its red, green and blue components. for a default greyscale, we normally multiply each color component with 0.33 ( 1 / 3 ). to obtain a brighter image, we have to multiply each component with a higher factor.
so, here are the steps to convert to monochrome :
1 - load original image to gdi+
2 - create a new temporary bitmap with the same size of the original
3 - create an imageattributes object
4 - apply a "greyscale" color matrix to image attributes
6 - draw the original image to the created bitmap using the imageattributes
7 - save the image
for this sample i created a loop in which the factor ranges from .10 to 1, to obtain different images.
do locfile("system.app")
with _screen.system.drawing
local lcimgfile
lcimgfile = getpict()
* create a bitmap object based on a bmp file.
local looriginalbmp as xfcbitmap
looriginalbmp = .bitmap.fromfile(lcimgfile)
local lotempbmp as xfcbitmap
lotempbmp = .bitmap.new(looriginalbmp.width, looriginalbmp.height)
local logfx as xfcgraphics
logfx = .graphics.fromimage(lotempbmp)
local loattr as xfcimageattributes
local logreyscalematrix as xfccolormatrix
local lomonochrbmp as xfcbitmap
local lorectbounds as xfcrectangle
lorectbounds = looriginalbmp.getbounds()
for lnfactor = .10 to 1 step .10
logreyscalematrix = _screen.system.drawing.imaging.colormatrix.new( ;
lnfactor, lnfactor, lnfactor, 0.0, 0.0, ;
lnfactor, lnfactor, lnfactor, 0.0, 0.0, ;
lnfactor, lnfactor, lnfactor, 0.0, 0.0, ;
0.0 , 0.0 , 0.0 , 1.0, 0.0, ;
0.0 , 0.0 , 0.0 , 0.0, 1.0)
loattr = null
loattr = .imaging.imageattributes.new()
loattr.setcolormatrix(logreyscalematrix)
* draw the image with the color matrix transformations
logfx.drawimage(looriginalbmp, lorectbounds, lorectbounds, 2, loattr)
lomonochrbmp = lotempbmp.getmonochrome()
* save the created monochromatic bmp
lomonochrbmp.save("c:\" + juststem(lcimgfile) + ;
transform(lnfactor * 100) + ".bmp", .imaging.imageformat.bmp)
endfor
endwith
return
and this time we can obtain better results, according to the desired factor.
original picture | ||||
factor = 10 | factor = 20 | factor = 30 | factor = 40 | factor = 50 |
factor = 60 | factor = 70 | factor = 80 | factor = 90 | factor = 100 |
original picture | ||||
factor = 10 | factor = 20 | factor = 30 | factor = 40 | factor = 50 |
factor = 60 | factor = 70 | factor = 80 | factor = 90 | factor = 100 |
related links:
utmag articles:
special effects on images with new gdiplus-x classes - part 1
special effects on images with new gdiplus-x classes - part 2