Y'herd thisun? 

“We well know, from repeated experience, how much misery and hardship men will undergo in their own country, before they can determine to desert it; and how often the most tempting proposals of embarking for new settlements have been rejected by people who appeared to be almost starving.”

from Principle of Population, Chapter 10 by Thomas Malthus

Your own image control and App part 12

TaggedCoding, VB, Imaging

Originally published December 2002 on using VB7.0/2002. Updated for VB7.1 February 2005

Links for compiled demo versions, all required resources and source code are included at the end of this article.

Plus, get the complete eBook in Adobe Acrobat 7 format ... all here.


12) Fixing the squish

Now that you can see whole images, the oddly sized fax pages are probably bothering the heck out of you. The reason for the "squishes" is the Fax transmission compression.

When you send a fax you can specify different quality/speed settings typically called "Draft" and "High"; Different machines allow different settings but these two are usually in the list somewhere. The difference is the image resolution. Along with converting full color sources to 1bitperpixel black and white format, fax compression traditionally trims down the number of bits by reducing the number of vertical pixels. A rule of thumb way to think of it is that every other vertical scanline is being removed, vertical thinning being the least noticeably impactive on the eye. Due to geeky things it's notreally halving the lines but the results are close enough that the analogy fits. To see this, right click and look at the advanced properties of our demo fax file and notice that the horizontal resolution is 204 but the vertical is only 98.

Because the compression technique is so common, Fax viewing applets such as the new Microsoft viewer or the older Wang and Kodak fax viewer applets automatically account for it and "put the pixels back". We have to do that too.

Open the ImageUtilities.vb file and wrap a conditional fix around the bmpDest constructor call (the bolded lines) of the CopyImage function:

'make bitmap for result
If SourceImage.HorizontalResolution <> SourceImage.VerticalResolution Then
bmpDest = _
New Bitmap(CInt(SourceImage.Width / SourceImage.HorizontalResolution) * 100, _
CInt(SourceImage.Height / SourceImage.VerticalResolution) * 100)
bmpDest = New Bitmap(SourceImage.Width, SourceImage.Height)
End If

Now if the source image's resolutions don't match, the destination bitmap width and height will be correctly adjusted. Remember that DrawImage is going to stretch the source graphic to fit the size of the destination bitmap so with this little calculation we're just correcting the destination area and DrawImage will fill in the gaps.

I'll mention up front that stretching the image this way will make the fully zoomed displays fuzzy. That's a result of the interpolation and there's not an easy way around it using GDI+ alone. You can try the different interpolation modes, multiplying the above calculations by 200 instead of 100, playing with the bmpDest.SetResolution method and get some minor enhancements but in the end using HighQualityBicubic and the display's native DotsPerInch setting ("DPI", as specified in you controller's advanced properties dialog) is best for all of the image types that the control will be displaying

Gotta change just one more thing. We coded LoadImage(img) so that it would only use the CopyImage function if a file had more than one pageframe, now we have to fix single page faxes so all image sources should be passed through the slicer. (Alternatively you could trust the file extension or even read the file headers, go for it if you feel very trusting.)

The update only requires removing the conditional from the array-filling section of LoadImage(img), trimming it down to this:

''reset the array to the number of pages
ReDim m_ImagePages(pageCount - 1)
For i As Integer = 0 To UBound(m_ImagePages)
tmpFileImage.SelectActiveFrame(FrameDimension.Page, i)
tmpFrameImage = DirectCast(tmpFileImage.Clone, Image)
tmpFrameImage = CopyImage(tmpFrameImage)
m_ImagePages(i).OriginalImage = tmpFrameImage
m_ImagePages(i).WorkingImage = DirectCast(tmpFrameImage.Clone, Image)
m_ImagePages(i).CurrentZoom = 100

Next: Zooming to fit

Robert Smith
Kirkland, WA

added to smithvoice march 2005

jump to:

  • 1) The spec
  • 2) Setting up the workspace
  • 3) Feature 1: Loading an image
  • 4) Custom Exceptions
  • 5) "Fax images" and Multipage TIFFs
  • 6) Custom events
  • 7) Selecting specific fax pages
  • 8) Feature 2: Rotating image displays
  • 9) The most useful tool in GDI+: DrawImage
  • 10) Feature 3: Zooming
  • 11) Handling the unhandleable exception
  • 12) Fixing the squish
  • 13) Zooming to fit the control
  • 14) You're already beating the Pros
  • 15) Feature 4: Cropping
  • 16) Bonus Feature: StickyMouse
  • 17a) Final Cleanup
  • 17b) Passing the current display image
  • 18) Making the application
  • 19) Source and result viewports
  • 20) A better toolbar
  • 21) Hooking the toolbar to the project
  • 22) Adding ImageEditors
  • 23) The toolbar ZoomCombo
  • 24) The final solution
  • 25) Saving to image files
  • 26) An integer-only textbox
  • 27) Passing save options between forms
  • 28) Dealing with that last exception
  • 29) Offer more options with menus
  • 30 The downloads and ebook

  • home     who is smith    contact smith     rss feed π
    Since 1997 a place for my stuff, and it if helps you too then all the better