Q: I would like to convert PDF shading elements to bitmaps, however I
cannot get the same result a PDFTron rasterizer.
I would like to render the shading object to the buffer whose bounding
box is decided by minCorner and maxCorner; Here the shading object is
indeed a shading pattern of a path element whose bounding box is
minCorner and maxCorner. What is wrong about my codes?
bool
PDFShadingObject::TranslateAxisShading(PDF::Element& element,
ITranslateTarget* pTarget, IADPDFSheetProperty* pSheet, double
minCorner[2], double maxCorner[2])
{
int width = (int)(maxCorner[0] - minCorner[0]+ 0.5);
int height = (int)(maxCorner[1] - minCorner[1] + 0.5);
if (width == 0 || height == 0)
return false;
int rowbyte = (width << 2);
int bufsize = rowbyte*height;
unsigned char* buffer = new unsigned char[bufsize];
unsigned char* temp = buffer;
double t0 = m_shading.GetParamStart ();
double t1 = m_shading.GetParamEnd ();
double x0, y0, x1, y1;
m_shading.GetCoords(x0, y0, x1, y1);
unsigned char opa= 255;//unsigned
char(element.GetGState().GetFillOpacity() * 255 + 0.5);
double xstart = minCorner[0];
double ystart = minCorner[1];
double denominator = (x1 - x0) * (x1 -x0) + (y1 - y0) * (y1 - y0);
double t = 0;
PDF::ColorPt clr;
PDF::ColorSpace cs = m_shading.GetBaseColorSpace();
for (int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
double x = ((x1 - x0) * (xstart - x0) + (y1 - y0) *
(ystart - y0)) / denominator;
if (x >= 0 && x <= 1)
t = t0 + (t1-t0) * x;
else if (x < 0)
{
t = t0;
}
else if (x > 1)
{
t = t1;
}
m_shading.GetColor(t, clr);
cs.Convert2RGB(clr, clr);
*temp++ = (unsigned char)(255*clr.Get(0)+ 0.5);
*temp++ = (unsigned char)(255*clr.Get(1)+ 0.5);
*temp++ = (unsigned char)(255*clr.Get(2)+ 0.5);
*temp++ = opa;
xstart += 1;
}
xstart = minCorner[0];
ystart += 1;
}
Common::Matrix2D sheetmatrix = pSheet->GetSheetMatrix();
sheetmatrix.Mult(minCorner[0], minCorner[1]);
sheetmatrix.Mult(maxCorner[0], maxCorner[1]);
if (minCorner[0] > maxCorner[0])
{
double temp = maxCorner[0];
maxCorner[0] = minCorner[0];
minCorner[0] = temp;
}
if (minCorner[1] > maxCorner[1])
{
double temp = maxCorner[1];
maxCorner[1] = minCorner[1];
minCorner[1] = temp;
}
double sincos[4]; // control rotation
PDFImage pimage (element);
pimage.GetRotationParams(sheetmatrix, sincos);
pTarget->ToRaster(buffer, width, height, sincos, minCorner,
maxCorner);
delete []buffer;
return true;
}
------------------
A: You may want to copy each shading element to a new temp page
(which is not added to the document using PagePushBack() or similar)
with a bounding box from a given element for the crop box. Then use
PDFDraw to rasterize the shading. PDF shading can be fairly tricky so
this approach will save you _lots_ of time and you will get the same
results and PDFTron rasterizer. In case you would like to draw shading
yourself, you may want to refer to PDF spec for details.