Foxite.COM Community Weblog

Foxite.COM Community Weblog - free weblog service for the Visual FoxPro Community.
Welcome to Foxite.COM Community Weblog Sign in | Join | Help
in
Home Blogs Forum Photos Forum Archives

VFP IMAGING



Convert Images to Monochrome with GdiPlus X

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

  1. Load Image to GdiPlus
  2. Call the Image.GetMonochrome to obtain a new object that will contain the 1bpp image
  3. 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

Using TIFFs with the new GDI+ classes

Published Tuesday, March 20, 2007 6:10 AM by cesarchalom

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

What do you think?

(required) 
(optional)
(required)