ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 Non-Visually Save MultiPage TIFF
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

Sidney Egnew

USA
51 Posts

Posted - Jul 07 2017 :  02:01:01  Show Profile  Reply
I was attempting to save multipage tiff files to PDF files using a TImageENMIO but was getting an access violation. I determined this was because teh ImageEnMIO must be linked to a ImageEnMView.

I changed the code to use a ImageEnMView.MIO:

ImageEnMView.MIO.LoadFromFileTIFF('test123.tif');
for I := 0 to ImageEnMIO.ParamsCount-1 do
  ImageEnMView.MIO.Params[I].PDF_Compression := ioPDF_jpeg;
ImageEnMView.MIO.SaveToFilePDF('test123_MIO3.pdf');


1) Is there a simpler way to do this without having to use visual component?

2) I need to save just the page fronts and did that with the code below. If there is a simpler solution, please indicate how to accomplish this as well.

3) What compression will provide the smallest PDF File?

4) The original TIFF size is 1,348,362. When I saved all pages, the PDF file size is 10,930,478. But when I save just the page fronts, the PDF file size is 1,152,511. The page backs are mostly blank. I saved just the backs and the file size is 568,577. Why is the file where I did not delete pages so much larger than the fronts+backs?

Thanks

ImageEnMView.MIO.LoadFromFileTIFF('test123.tif');
for I := ImageEnMIO.ParamsCount-1 downto 0 do
begin
  ImageEnMView.MIO.Params[I].PDF_Compression := ioPDF_jpeg;
  if System.Odd(I) then
    ImageEnMView.DeleteImage(I);
end;
ImageEnMView.MIO.SaveToFilePDF('test123_MIO4.pdf');

xequte

38180 Posts

Posted - Jul 08 2017 :  15:40:46  Show Profile  Reply
Hi

1. Yes, use TIEMultiBitmap:

https://www.imageen.com/help/TIEMultiBitmap.html

Your code would be something like:

MyMBMP := TIEMultiBitmap.Create;
MyMBMP.ParamsEnabled := True;
MyMBMP.Read('D:\test123.tif');
for I := 0 to MyMBMP.Count-1 do
  MyMBMP.Params[I].PDF_Compression := ioPDF_jpeg;
MyMBMP.Write('D:\test123_MIO3.pdf');
MyMBMP.Free;



2.

MyMBMP :- TIEMultiBitmap.Create;
MyMBMP.ParamsEnabled := True;
MyMBMP.Read('D:\test123.tif');
for I := MyMBMP.Count - 1 downto 0 do
begin
  if System.Odd(I) then
    MyMBMP.DeleteImage(I)
  else
    MyMBMP.Params[I].PDF_Compression := ioPDF_jpeg;
end;
MyMBMP.Write('D:\test123_MIO3.pdf');
MyMBMP.Free;



3. Well, it depends on the file content. If the TIFF will cope with lossy compression (e.g. photos), then ioPDF_jpeg. But more likely with TIFF's, they will be documents, so you want lossless compression, so ioPDF_LZW.


4. Can you email me the TIFF file for testing.



Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Jul 14 2017 :  07:23:50  Show Profile  Reply
Nigel:

TIEMultiBitmap does not have ParamsCount so your example does not work.
for I := MyMBMP.ParamsCount-1 downto 0 do

I get an access violation when I tried using MyMBMP.Count instead. Please advise on the correct solution.

Thanks, Sidney
Go to Top of Page

xequte

38180 Posts

Posted - Jul 15 2017 :  01:41:54  Show Profile  Reply
Hi Sidney

Sorry, it is .Count, I have corrected the code. Can you show me your code that produces an A/V

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 09 2017 :  05:58:34  Show Profile  Reply
My procedure is below. The access violation occurs when attempting to set PDF_Compression.

procedure TfmMain.SaveAllPdf(FileName,ScanPageNo: String);
var
  I: Integer;
  TargetFileName: String;
  MBitmap: TIEMultiBitmap;
begin
  TargetFileName := 'Test.pdf';
  LogMessage(TargetFileName);
  MBitmap := TIEmultiBitmap.Create(nil);
  try
    MBitmap.Read(FileName);
    for I := MBitmap.Count-1 downto 0 do
    begin
      MBitmap.Params[I].PDF_Compression := ioPDF_Lzw;  //<<<--- AV occurs here
    end;
    if not FileExists(TargetFileName) then
      MBitmap.Write(TargetFileName);
  finally
    MBitmap.Free;
  end;
end;
Go to Top of Page

xequte

38180 Posts

Posted - Aug 09 2017 :  17:13:03  Show Profile  Reply
Hi Sidney

You will need to set:

MBitmap.ParamsEnabled := True;

Please see the documentation at:

https://www.imageen.com/help/TIEMultiBitmap.Params.html

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 09 2017 :  18:06:21  Show Profile  Reply
Thanks, this setting eliminated the access violation.

However, there is still a problem. Some of our scanned files are very large and cause an "Out of Memory" exception. The particular file being processed has 650 pages scanned into a TIFF file which is 201 MB. The file needs to be converted to a PDF but the "Out Of Memory" exception is preventing the current routine from working.
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 10 2017 :  08:19:01  Show Profile  Reply
1) In addition to the "Out of Memory" error, access violations are still occurring. I have not yet determined the specific code where the access violation is occurring but it occurs in the code shown below without the target file being created. An access violation occurred 9 times out of 126 files being processed. The AV appears to have occurred only for files over 27 MB. All smaller files were processed without an error.

Here is the code to convert to a PDF with all pages:
MBitmap := TIEmultiBitmap.Create(nil);
      try
        MBitmap.ParamsEnabled := True;
        MBitmap.Read(FileName);
        MBitmap.Params[0].PDF_Compression := ioPDF_LZW;
        MBitmap.DuplicateCompressionInfo;
        W := MBitmap.ImageWidth[0];
        H := MBitmap.ImageHeight[0];
        PageCount := MBitmap.Count;
        LogMessage(TargetFileName+' W='+IntToStr(W)+' H='+IntToStr(H)+' Pages='+IntToStr(PageCount));
        if W > H then
          MBitmap.RotateAll(270);
        MBitmap.Write(TargetFileName);
      finally
        MBitmap.Free;
      end;


2) The process is very slow and I have to write four files and delete the pages I don't need as I go. Here are the files being written:

TIFF to PDF (All Pages)
TIFF to PDF (Fronts Only)
Extract Page 0 as a TIFF
Extract Page 1 as a TIFF

I think it would be better to just a second TIEMultiBitmap and build the new image, at least for the single page extraction. How can I accomplish this?

Here is the code to extract the first page as currently written:
MBitmap := TIEmultiBitmap.Create(nil);
      try
        MBitmap.ParamsEnabled := True;
        MBitmap.Read(FileName);
        MBitmap.Params[0].PDF_Compression := ioPDF_LZW;
        MBitmap.DuplicateCompressionInfo;
        W := MBitmap.ImageWidth[0];
        H := MBitmap.ImageHeight[0];
        PageCount := MBitmap.Count;
        LogMessage(TargetFileName+' W='+IntToStr(W)+' H='+IntToStr(H)+' Pages='+IntToStr(PageCount));
        for I := MBitmap.Count-1 downto 0 do
        begin
          if I <> 0 then
            MBitmap.DeleteImage(I);
        end;
        if W > H then
          MBitmap.RotateAll(270);
        MBitmap.Write(TargetFileName);
      finally
        MBitmap.Free;
      end;


3) The input TIFF files are scanned copies of 8 1/2 x 11 documents. The PDF files have been scaled smaller than the originals. I need the PDF to be exactly like the original TIFF. What needs to be set to accomplish this?

Thanks



Go to Top of Page

xequte

38180 Posts

Posted - Aug 10 2017 :  17:09:36  Show Profile  Reply
Hi Sidney

TIEMultiBitmap supports disk caching. By default, after ten images they are cached to disk. Please see:

https://www.imageen.com/help/TIEMultiBitmap.ImageCacheUseDisk.html

Regarding the PDF document size, what have you set for:

https://www.imageen.com/help/TIOParams.PDF_PaperSize.html

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

xequte

38180 Posts

Posted - Aug 10 2017 :  17:14:26  Show Profile  Reply
Also, to extract a single page from a TIFF, you are better just to use a TIEBitmap and set Params.ImageIndex:

// Load the third image in a TIFF and save it to JPEG
aBmp := TIEBitmap.create;
aBmp.ParamsEnabled := True; // Load params with the image
aBmp.Params.ImageIndex := 2;
aBmp.Read( 'C:\MyTiffDoc.TIFF' );
aBmp.Params.JPEG_Quality := 70;
aBmp.Write( 'D:\Page3.jpeg' );
aBmp.Free;


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 11 2017 :  01:50:34  Show Profile  Reply
The only problem that remains is large files. I had no problem using a TIEBitmap to cycle thru all the pages in the files. However when I attempted to assemble the individual pages using a TIEMultiBitmap, I had some problems.

The problem with large file sizes causing an access violation remains. There was another issue in that the output file was many time larger than expected.

I really need a solution for this. Do you know when something will be available?

Thanks
Go to Top of Page

xequte

38180 Posts

Posted - Aug 11 2017 :  18:03:31  Show Profile  Reply
Hi Sidney

Can you please send me your source TIFF file and the steps to reproduce the A/V?

You will probably need to use a file sharing service if the TIFF file is big.

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 15 2017 :  01:10:02  Show Profile  Reply
Nigel:

Here is the code. I will send you an email with a link to a large TIFF.

Thanks, Sidney

procedure TfmMain.SaveAllPdf(FileName,ScanPageNo: String);
var
  I,W,H,PageCount: Integer;
  TargetFileName: String;
  MBitmap: TIEMultiBitmap;
begin
  TargetFileName := 'nigel.pdf';
  MBitmap := TIEmultiBitmap.Create(nil);
  try
    MBitmap.ParamsEnabled := True;
    MBitmap.Read(FileName);
    W := MBitmap.ImageWidth[0];
    H := MBitmap.ImageHeight[0];
    PageCount := MBitmap.Count;
    LogMessage(TargetFileName+' W='+IntToStr(W)+' H='+IntToStr(H)+' Pages='+IntToStr(PageCount));
    if W > H then
      MBitmap.RotateAll(270);
    for I := 0 to PageCount-1 do
      begin
        MBitmap.Params[I].PDF_PaperSize := iepAuto;//iepLetter;
        MBitmap.Params[I].PDF_Compression := ioPDF_LZW;
      end;
    MBitmap.Write(TargetFileName);
  finally
    MBitmap.Free;
  end;
end;
Go to Top of Page

xequte

38180 Posts

Posted - Aug 17 2017 :  02:20:05  Show Profile  Reply
It should work as follows:

procedure TfmMain.SaveAllPdf(FileName,ScanPageNo: String);
var
  I,W,H,PageCount: Integer;
  TargetFileName: String;
  MBitmap: TIEMultiBitmap;
begin
  TargetFileName := 'nigel.pdf';
  MBitmap := TIEmultiBitmap.Create(nil);
  try
    MBitmap.ImageCacheUseDisk := true;
    MBitmap.ImageCacheSize := 1;
    MBitmap.ParamsEnabled := True;
    MBitmap.Read(FileName);
    W := MBitmap.ImageWidth[0];
    H := MBitmap.ImageHeight[0];
    PageCount := MBitmap.Count;
    for I := 0 to PageCount-1 do
    begin
      MBitmap.Params[I].PDF_PaperSize := iepAuto;//iepLetter;
      MBitmap.Params[I].PDF_Compression := ioPDF_LZW;
    end;
    MBitmap.Write(TargetFileName);
  finally
    MBitmap.Free;
  end;
end;


Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

Sidney Egnew

USA
51 Posts

Posted - Aug 19 2017 :  02:03:32  Show Profile  Reply
Nigel:

This solution works well.

Thank you very much, Sidney
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: