Dear Group,
I read through the thread posted on January 10th of this year, "Resize Image => unwanted border appears in resulting image w/HighQualityBicubic Interp.", but my problem doesn't seem to be solved by the method that poster found for himself.
My task is to take large bitmaps and 1) resample/resize them to reduce them before 2) slicing them up into small pieces (256 x 256 pixels) for later re-assembly in a web browser.
I've used Visual Studio 2005 to create a test Windowsform. In my test I've carved up a large bitmap (18,257 x 21,909 pixels) in TIFF format into nine 8192 x 8192 pixel chunks and saved them as BMP's. The far right-hand and bottom "chunks" are different dimensions due to the fact that the original bitmap isn't an even multiple of 8192 in either dimension. These intermediate-sized chunks can be re-assembled perfectly in a web browser.
Then I've taken each of these 8192 x 8192 pixel BMP files and resized them at five different "magnification" levels: 50%, 25%, 12.5%, 6.25%, and 3.125%...all factors of two smaller than the original. All reduced images are saved with JPEG compression.
As in the original January 10th post, the reduced-size images all acquire a top and left border as long as the InterpolationMode is set to either HighQualityBicubic, HighQualityBilinear, or High (the same as HighQualityBicubic to my eyes). If the InterpolationMode is set to one of the lower quality modes there are no borders...but the image quality stinks.
Here is the code I used to perform the resize test (the 8192 x 8192 pixel BMP chunks have already been saved to disk by this time):
Dim ici As ImageCodecInfo
Dim eps As EncoderParameters = New EncoderParameters(1)
eps.Param(0) = New EncoderParameter(Encoder.Quality, 100)
'---GetEncoderInfo() is a custom function to retrieve Encoder info
ici = GetEncoderInfo("image/jpeg")
Dim pxf As PixelFormat
Dim i As Integer
Dim j As Integer
Dim intStripeW As Integer
Dim intStripeH As Integer
Dim intMag As Integer
Dim destW As Integer
Dim destH As Integer
Dim bmpStripe As Bitmap
Dim bmpShrunkenStripe As Bitmap
Dim g As Graphics
For i = 0 To 16384 Step 8192
For j = 0 To 16384 Step 8192
'---Open each BMP and apply
' multiple magnification levels to it.
bmpStripe = New Bitmap("C:\Temp\TestImg_X" & _
i & "_Y" & j & ".bmp", False)
pxf = bmpStripe.PixelFormat
If i = 16384 Then
intStripeW = bmpStripe.Width
Else
intStripeW = 8192
End If
If j = 16384 Then
intStripeH = bmpStripe.Height
Else
intStripeH = 8192
End If
'//////// Magnification Loop
For intMag = 0 To 5
destW = CInt(intStripeW / (2 ^ intMag))
destH = CInt(intStripeH / (2 ^ intMag))
bmpShrunkenStripe = New Bitmap(destW, destH, pxf)
g = Graphics.FromImage(bmpShrunkenStripe)
g.InterpolationMode = _
Drawing2D.InterpolationMode.HighQualityBicubic
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
g.CompositingQuality = _
Drawing2D.CompositingQuality.HighQuality
' This was my original stab at pouring the BMP
' into a smaller box.
' g.DrawImage(bmpStripe, 0, 0, _
' bmpShrunkenStripe.Width, bmpShrunkenStripe.Height)
g.DrawImage(bmpStripe, _
New Rectangle(-1, -1, destW + 2, destH + 2), _
New Rectangle(0, 0, intStripeW, intStripeH), _
GraphicsUnit.Pixel)
g.Dispose()
bmpShrunkenStripe.Save("C:\Temp\TestImg_X" & _
i & "_Y" & j & "_M" & intMag & ".jpg", ici, eps)
bmpShrunkenStripe.Dispose()
Next intMag
bmpStripe.Dispose()
Next j
Next i
As you can see, I tried the trick suggested on January 10th to offset the rectangle a bit when copying from the source to the destination rectangle. That's what the -1, -1 co-ordinates mean in the first New Rectangle definition. I got incorrect results using two variations of that line. That is, using
New Rectangle(-1, -1, destW + 2, destH + 2), _
as suggested on January 10th,a single column of pixels and a single row of pixelswere removed from two of the edges of each chunk. On the other hand, using
New Rectangle(-1, -1, destW + 1, destH + 1), _
caused a border of pixels to appear along the RIGHT and BOTTOM edges of each chunk instead of along the top and left edges!
As I say, this offsetting method for defining the size and placement of the re-sized chunks is one I gleaned from the January 10th posting in this forum.
I conducted many tests using various combinations of PixelOffsetMode, CompositingQuality, and SmoothingMode to try to get rid of the HighQualityBicubic borders. I found that there were four different shades of gray borders that would appear based on the combination of properties used while re-sizing the image:
8E8E8E
C4C4C4
EEEEEE
F6F6F6
I only tested the HighQualityBicubic InterpolationMode with all of the combinations of the other properties because I definitely am looking for the best quality re-sizing I can get. However, even though a border of F6F6F6 is *almost* white, it still shows up plainly when the chunks are assembled in a browser.
Is this a bug in the InterpolationMode.HighQualityBicubic? Is there any other workaround?
Thanks very much in advance.
Steve Erbach
Neenah, WI
http://TheTownCrank.blogspot.com