Ok what's happening is I'm pulling in a Tiff file that can have multiple pages. I selected the first frame, draw a stamp image to it and save it as a different file name.
When I do this, it is only saving the first page of the tiff file. How do I get all of the pages to save?
Ok, I figured out what to do to get the pages all together after I add the stamp to the first page. I have another problem though.
I'm using an Export function provided by our third party DMS software vendor.
The resulting tiff image (when exported) has a compressionLZW, and for some reason the tifftopdf function they provided doesn't like that compression and the pdf's are unreadable. But if it exports the the file with a compressionCCITT4 then the tifftopdf function makes a good pdf file.
My problem is, when I open the image to add the stamp, when I save it, it has a compression of LZW, even though the original file had the CCITT4.
The error is "Parameter not valid". And it's referring to the compression encoderparameter I'm sure, because if I change it to the Encodervalue.compressionLZW it doesn't complain.
Code:
Dim enc As Encoder = Encoder.SaveFlag
Dim enc2 As Encoder = Encoder.Compression
Dim ep As New EncoderParameters(2)
Dim info As ImageCodecInfo = Nothing
For Each ice As ImageCodecInfo In ImageCodecInfo.GetImageEncoders
MessageBox.Show(ice.MimeType.ToString)
If ice.MimeType = "image/tiff" Then
info = ice
End If
Next
ep.Param(0) = New EncoderParameter(enc2, CType(EncoderValue.CompressionCCITT4, Long))
ep.Param(1) = New EncoderParameter(enc, CType(EncoderValue.MultiFrame, Long))
Dim fileExt As String = NetDMS.exportDocumentImageWithAnnotations(_workflow, disn(0), "C:\JCEmailFld", "emailDocument" + currEmailDoc.ToString)
Dim documentFile As Image = Image.FromFile("C:\JCEmailFld\" + "emailDocument" + currEmailDoc.ToString + fileExt)
Dim temp As New Bitmap(documentFile.Width, documentFile.Height, PixelFormat.Format32bppArgb)
temp.SetResolution(documentFile.HorizontalResolution, documentFile.VerticalResolution)
Try
Dim graph As Graphics = Graphics.FromImage(CType(temp, Image))
graph.DrawImage(CType(documentFile, Image).Clone, New Point(0, 0))
graph.Dispose()
Catch ex As Exception
End Try
documentFile = CType(temp, Image)
Dim stampFile As Bitmap = Bitmap.FromFile("\\visiflowserver1\visiflow\netDMS\Stamps\DClerkCertifiedCopy.gif")
For i As Integer = 235 To 255
stampFile.MakeTransparent(Color.FromArgb(i, i, i))
Next
documentFile.SelectActiveFrame(FrameDimension.Page, 0)
Try
Dim g As Graphics = Graphics.FromImage(CType(documentFile, Image))
g.DrawImage(CType(stampFile, Image).Clone(), CInt(stampFile.Width / 4), ((documentFile.Height - stampFile.Height) - CInt(stampFile.Height / 2)), stampFile.Width, stampFile.Height)
g.Dispose()
Catch ex As Exception
MessageBox.Show("Error applying stamp: " + ex.Message)
End Try
If fileExt = ".TIF" Then
documentFile.Save("C:\JCEmailFld\" + disn(1) + currEmailDoc.ToString + ".TIF", info, ep)
ep.Param(1) = New EncoderParameter(enc, CType(EncoderValue.FrameDimensionPage, Long))
For k As Integer = 1 To documentFile.GetFrameCount(FrameDimension.Page) - 1
documentFile.SelectActiveFrame(FrameDimension.Page, k)
documentFile.SaveAdd(documentFile, ep)
Next
ep.Param(1) = New EncoderParameter(enc, CType(EncoderValue.Flush, Long))
documentFile.SaveAdd(ep)
Else
documentFile.Save("C:\JCEmailFld\" + disn(1) + currEmailDoc.ToString + ".BMP", ImageFormat.Bmp)
End If
documentFile.Dispose()
stampFile.Dispose()
Thanks,
Justin
You down with OOP? Yeah you know me!
MCAD and MCMICKEYMOUSE (vb.net)
Ok so I've boiled down the specific problem now. I can open a bunch of single page tif files, and then add them to each other with the imagecodecinfo and encoder parameters and the compression saves and is all good.
The problem comes, when I open a tif file, draw an image to it, save it as a tif with the imageformat, and then re open it and save it with the imagecodecinfo and the encoder params.
Here is a snippet of code that throws the error.
vb Code:
Dim comEncoder As Encoder = Encoder.Compression
Dim savEncoder As Encoder = Encoder.SaveFlag
Dim ep As New EncoderParameters(2)
ep.Param(0) = New EncoderParameter(comEncoder, CLng(EncoderValue.CompressionCCITT4))
ep.Param(1) = New EncoderParameter(savEncoder, CLng(EncoderValue.MultiFrame))
Dim codecInfo As ImageCodecInfo = GetCodecInfo("image/tiff")
Dim finalImageName As String = ""
Dim edittedPageName As String = ""
Dim bitmap As Bitmap = bitmap.FromFile("C:\JCEmailFld\MultiPageCCITT4Compression.tif") 'has indexed pixel format.
Dim stamp As Bitmap = bitmap.FromFile("\\visiflowserver1\visiflow\netDMS\Stamps\DClerkCertifiedCopy.gif")
Dim nonindexedstamp As Bitmap 'object that holds the new nonindex pixel format stamp
'convert stamp to nonindexed pixelformat as well (format24bpprgb)
If Not stamp.PixelFormat = PixelFormat.Format24bppRgb Then
nonindexedstamp = New Bitmap(stamp.Width, stamp.Height, PixelFormat.Format24bppRgb)
Dim g As Graphics = Graphics.FromImage(CType(nonindexedstamp, Image))
g.DrawImage(CType(stamp, Image), New Point(0, 0))
g.Dispose()
End If
Dim pageFiles As New ArrayList
'Save each page as an individual tiff file.
For i As Integer = 0 To bitmap.GetFrameCount(FrameDimension.Page) - 1
bitmap.SelectActiveFrame(FrameDimension.Page, i)
Dim filename As String = "C:\JCEmailFld\" + Now.ToFileTime.ToString + "_Page" + i.ToString + ".tif"
bitmap.Save(filename)
pageFiles.Add(filename)
Next
bitmap.Dispose()
'get the first page.
Dim firstPage As Bitmap = bitmap.FromFile(pageFiles(0))
Dim edittedFirstPage As Bitmap 'The bitmap we'll store the newly editted first page to.
'if the tif image has an indexed pixel format or an undefined one create a new
'bitmap image with format24bpprgb (or any other format besides indexed so we can
'get a graphics object to draw on).
If firstPage.PixelFormat = PixelFormat.Format1bppIndexed Or _
firstPage.PixelFormat = PixelFormat.Format4bppIndexed Or _
firstPage.PixelFormat = PixelFormat.Format8bppIndexed Or _
firstPage.PixelFormat = PixelFormat.Indexed Or _
firstPage.PixelFormat = PixelFormat.Undefined Then
Dim temp As New Bitmap(firstPage.Width, firstPage.Height, PixelFormat.Format24bppRgb) 'the new bitmap we will draw the first page to.
Dim g As Graphics = Graphics.FromImage(CType(temp, Image))
g.DrawImage(CType(nonindexedstamp, Image), New Point(0, 0))
g.Dispose()
Dim newFileName As String = "C:\JCEmailFld\" + Now.ToFileTime.ToString + "_EdittedPage0.tif"
temp.Save(newFileName, ImageFormat.Tiff)
temp.Dispose()
edittedFirstPage = bitmap.FromFile(newFileName)
End If
'Save the edittedfirstpage as tiff with codecInfo and Mulitpage/Compression parameters.
Dim newFileName As String = "C:\JCEmailFld\" + Now.ToFileTime.ToString + "_EdittedPage0.tif"
'I thought saving the file with a tiff format first, the reopening to add the other pages would fix the problem,
'but it didn't.
temp.Save(newFileName, ImageFormat.Tiff)
temp.Dispose()
firstPage.Dispose()
edittedFirstPage = bitmap.FromFile(newFileName)
End If
'Now to convert the image back to an indexed1bbp format
Dim bmdo As BitmapData = edittedFirstPage.LockBits(New Rectangle(0, 0, edittedFirstPage.Width, edittedFirstPage.Height), ImageLockMode.ReadOnly, edittedFirstPage.PixelFormat)
'and the new 1bpp bitmap
Dim bm As New Bitmap(edittedFirstPage.Width, edittedFirstPage.Height, PixelFormat.Format1bppIndexed)
Dim bmdn As BitmapData = bm.LockBits(New Rectangle(0, 0, bm.Width, bm.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed)
'for diagnostics
Dim dt As DateTime = DateTime.Now
'scan through the pixels Y by X
Dim y As Integer
For y = 0 To edittedFirstPage.Height - 1
Dim x As Integer
For x = 0 To edittedFirstPage.Width - 1
'generate the address of the colour pixel
Dim index As Integer = y * bmdo.Stride + x * 4
'check its brightness
If Color.FromArgb(Marshal.ReadByte(bmdo.Scan0, index + 2), Marshal.ReadByte(bmdo.Scan0, index + 1), Marshal.ReadByte(bmdo.Scan0, index)).GetBrightness() > 0.5F Then
Me.SetIndexedPixel(x, y, bmdn, True) 'set it if its bright.
End If
Next x
Next y
'tidy up
bm.UnlockBits(bmdn)
edittedFirstPage.UnlockBits(bmdo)
'Save the edittedfirstpage as tiff with codecInfo and Mulitpage/Compression parameters.
Re: [RESOLVED] Drawing image to Multi-page tiff file.
Here is the final class I wrote to encompass what I was trying to accomplish along with allowing to draw to any page on the tiff and able to save the Tiff file with compressions: CCITT4, CCITT3, LZW, Rle and None.
Everything would work for anyone wanting to use this class except for the SaveAsPDF Sub. You would need to make or get your own 3rd party tools for that functionality to work.
It always converts each page of the tif file to Format32bppPArgb for potential editting. It may be more efficient to only convert when you actually call an editing method in the Page object.
When Save is called, it converts each page to Format1bppIndexed, creates the multipage tif file and then saves it.
I had to attach it, it was too big to paste in here... even just the TiffImage class.
Here is how you'd use it though:
vb Code:
Dim tiffFile As New JCUtilities.Imaging.TiffImage("C:\JCEmailFld\MultiPageCCITT4Compression.tif", "C:\Images")
Re: [RESOLVED] Drawing image to Multi-page tiff file.
I used your ConvertToFormat1bppIndexedFrom32bppPArgb method. I am getting the larger image sizes than the original !! (The orignal size was 645 KB and the result file was
Re: [RESOLVED] Drawing image to Multi-page tiff file.
I used your ConvertToFormat1bppIndexedFrom32bppPArgb method. I am getting the larger image sizes than the original !! (The orignal size was 645 KB and the result file was 6715 KB). Could you please tell me what might be the problem?
Since we are using the lesser pixel format, I was expecting the image size would reduce a lot !!
Re: [RESOLVED] Drawing image to Multi-page tiff file.
Hi Justin,
It happens to any tiff file, I used.
Here is the workflow, I am following.
The original Image is "Format1bppIndexed" and resolution is 2600 X 4200 (it varies depends on the images) with 300 dpi. Sometimes the images having with lot of white space during the image scan.
According to our requirement, the image needs to be stretched to fit the full page view. So I resized the resolution as 1800 X 2400 and 96 dpi, to make it fit to full page, which worked perfectly.
During this process, I had to convert the image to Format32bppRgb, which blotted the file size, causing to consume more memory when I open more images.
I wanted to compress the file size, so used the method "ConvertToFormat1bppIndexedFrom32bppPArgb", which didn't reduce the file size.
Earlier I used the code "resize-multipage-tiff" from a VB.NET forum, which also had the same size issue.
Once again, thanks a lot for helping me.
Thanks
- Venkat
Last edited by dear_vvr; Apr 2nd, 2012 at 02:32 PM.
Re: [RESOLVED] Drawing image to Multi-page tiff file.
Oh ok, well I'll give it a test and see what my result is in the actual file size. I kind of did away with keep all the images in memory. With big multi-page tiff files it just isn't practical as you'll use so much memory it's crazy.
I just had it to where the user of the API call could specify a temp folder to create the individual page files and keep the paths in a list (of String).
I'll post later with some more information.
You down with OOP? Yeah you know me!
MCAD and MCMICKEYMOUSE (vb.net)
Re: [RESOLVED] Drawing image to Multi-page tiff file.
Hi Justin,
I ran the test on few more tiff files and the compression works fine.
I tried with a 176KB file to resize with Format32bppRgb, the resultant size is 2372 KB.
When I applied the ConvertToFormat1bppIndexedFrom32bppPArgb method, I came done to 162 KB.
The same file to resize with Format24bppRgb, the size is 1718 KB.
This time the method ConvertToFormat1bppIndexedFrom32bppPArgb didn't produce correct output file. Do I need to change the method "SetIndexedPixel" for this?
Just FYI... the time took without compression is 3.8 sec and with calling the compression method, 10.5 sec, almost 2.5 times slower !!
And I agree that, when we hold all the images in memory it is a problem. One of our client complains that, when he try to use 40 images (total 240 pages), the RAM zooms to 1 GB and the program throws "Insufficent memory exception" due to 32 bit OS limitations.
Thanks
Last edited by dear_vvr; Apr 2nd, 2012 at 03:50 PM.
Re: [RESOLVED] Drawing image to Multi-page tiff file.
I tried with a 176KB file to resize with Format32bppRgb, the resultant size is 2372 KB.
When I applied the ConvertToFormat1bppIndexedFrom32bppPArgb method, I came done to 162 KB.
The same file to resize with Format24bppRgb, the size is 1718 KB.
This time the method ConvertToFormat1bppIndexedFrom32bppPArgb didn't produce correct output file. Do I need to change the method "SetIndexedPixel" for this?
The method only correctly converts the file if the source image it's trying to convert to 1bppindexed is in the 32bppPArgb format. 24bppRgb will not convert correctly and may actually be corrupt, not sure though.
What I would do is right of the bat make sure the image is in the 32bpp format, if not, make it so.
Justin
You down with OOP? Yeah you know me!
MCAD and MCMICKEYMOUSE (vb.net)
Re: [RESOLVED] Drawing image to Multi-page tiff file.
I'm not sure how or why (in-depth), the setPixel code works... When I came up with this solution, I was in a bind and a hurry. You can always go to that site and email the guy to see how you would use the setPixel on a 24bppRgb pixel formatted image.
Justin
You down with OOP? Yeah you know me!
MCAD and MCMICKEYMOUSE (vb.net)