Q: I run into a problem when rendering images with high resolution
(when DPI is 500 for a fairly large page). PDFNet code snippet looks
along the following lines:
C++ Code snippet:
STDMETHODIMP CreateThumbnails(BSTR inputpath, BSTR outpath, double
res,int formato,int space,int giro,BSTR Profile)
{
USES_CONVERSION;
HRESULT hr = S_FALSE;
string input_path = OLE2T(inputpath);
string output_path = OLE2T(outpath);
string profile = OLE2T(Profile);
try
{
if(space == 5)
{
string iccfile = GetResourcesPath();
PDFNet::SetColorManagement(true);
if(profile.length() > 0)
iccfile += profile;
else
iccfile += "icc\\Photoshop4DefaultCMYK.icc";
PDFNet::SetDefaultDeviceCMYKProfile(iccfile.c_str());
string iccrgb = GetResourcesPath() +
"icc\\AdobeRGB1998.icc";
PDFNet::SetDefaultDeviceRGBProfile(iccrgb.c_str());
}
}
catch(Common::Exception& e)
{
PDFNet::SetColorManagement(false);
}
try
{
PDFDoc doc(input_path.c_str());
doc.InitSecurityHandler();
PDFDraw draw;
draw.SetDPI(res);
char format[32];
switch(formato)
{
case 2:
strcpy(format,"TIFF");
break;
case 6:
strcpy(format,"JPEG");
break;
}
SDF::ObjSet hints;
Obj space_hint = hints.CreateDict();
switch(space)
{
case 1:
space_hint.PutName("ColorSpace", "Gray");
break;
case 2:
space_hint.PutName("ColorSpace", "RGB");
break;
case 5:
space_hint.PutName("ColorSpace", "CMYK");
}
PageIterator itr = doc.GetPageIterator();
Page page = itr.Current();
if(page)
{
switch(giro / 90)
{
case 0:
page.SetRotation(Page::e_0);
break;
case 1:
page.SetRotation(Page::e_90);
break;
case 2:
page.SetRotation(Page::e_180);
break;
case 3:
page.SetRotation(Page::e_270);
break;
}
draw.Export(page,output_path.c_str(),format,space_hint);
//exception when do two times simultaneous on release version
hr = S_OK;
}
}
catch(Common::Exception& e)
{
const char* msg = e.GetMessage();
...
}
catch(...)
{
}
return hr;
}
-----
A: You are most likely running out of memory. As you increase the DPI
the memory requirements are increasing exponentially (and on 32 bit
systems there is a maximum memory allocation of 2GB).
If you need to rasterize PDF pages at very high DPI you may want to
either:
a) Rasterize the page in stripes/tiles using page.SetCropBox
(stripe_bbox) to indicate the sub region of the page to rasterize. For
example, if the input page has a media box [0,0,595,842] (e.g.
tiger.pdf from PDFNet/Samples/TestFiles folder), you could render the
page at 2000 DPI (Dots Per Inch) in four stripes (using 210.5 point
increments along the Y axis) as follows:
pdfdraw.SetDPI(2000);
page.SetCropBox(Rect(0,0,595,210.5));
pdfdraw.GetBitmap(page); ...
page.SetCropBox(Rect(0,210.5,595,421));
pdfdraw.GetBitmap(page); ...
page.SetCropBox(Rect(0,421,595,631.5));
pdfdraw.GetBitmap(page); ...
page.SetCropBox(Rect(0,631.5,595,842));
pdfdraw.GetBitmap(page); ...
This way you would effectively cut down on the memory requirements by
a factor of 4.
You can encapsulate the above approach in a utility class that will
use PDFDraw to render a PDF page (at any DPI) in stripes or tiles.