|
|
I really do not understand your difficulties.
1. PdfImageObject.BoundingBox - will give you the actual location and size of the image in points (in the page coordinate system). these coordinates are independent on render size, rotation, etc. One PDF point is 1/72 inches. 2. PdfPage.PageToDevice - allows you to translate points into pixels. Pixels, of course, depend on how you rendered the document, so you need to pass the same parameters to this method as when rendering 3. The origin of the page coordinate system (point with coordinates 0; 0) is located in the lower left corner of the page. 4. The origin of the "pixel coordinate system" is the upper left corner of the bitmap into which you render the page. 5. You must take into account that the page can be rotated at an angle of 90,180 or 270 degrees. The coordinates in the page coordinate system are independent of page rotation, in contrast to the coordinates in pixels. In order not to get a negative width or height, you should take this into account.
At what stage do you encounter difficulties? Please formulate a specific question with code examples and a PDF document.
|
|
|
Hi Paul
1. from all discussions above, can you supply in this thread, a corrected version , how to extract the images from a PDF+ coordinates in points, and then in pixels (as written in ..ToDevice...)
2. are the calculation of extracted rectangles , of mr. jacksonsavitraz correct ?
we don't have any documentation how treat rectangles that coming with minus values like (x,-y,w,-h...)
after having the correct code example (that not found in whole site) I'll check it.
and then supply: my demo PDF is simple with one image on top of page (some logo) and image of signature (down the page)
wait for help,
|
|
|
Hello,,
Please clarify your question in more details. What do you mean when talking about coordinates? In what coordinate system should these coordinates be indicated? Why do you think that the coordinates obtained using GetBoundingBox are incorrect? Please provide your test PDF and minimal code illustrating the problem.
|
|
|
extract images from pdf with coordinates.
still getting wrong pixel coordinates
can somebody help, give link of complete c# code example , I use very simple pdf with image on head page header.
PdfImageObject.Matrix - giving same results
so long time, no-body uses such a feature ?
|
|
|
Originally Posted by: Guest  I also didnot find any code example how to extract images from pdf , with it's coordinates (locations) in pixels ?
Try checking the PdfImageObject.Matrix. This will give you the location of the image in the fields e and f of the matrix. Width and height can be in a and d. These values are given in PDF points. 1 PDF point is 1/72 of an inch. Therefore, if you need pixels, just calculate them taking into account the DPI of the image you have rendered. pixel = point / 72.0 * dpi;
|
|
|
Pdfium.FPDFPageObj_GetBBox(img.Handle, form.Matrix, out l, out t, out r, out b) paul, can you rewrite the code above with the object method _GetBBox ?, I also didnot find any code example how to extract images from pdf , with it's coordinates (locations) in pixels ?
I still getting wrong, rectangles coordinates of the extracted images (?)
|
|
|
Well... my previous answer is incorrect. Thanks for having pointed out my misunderstanding of this issue. I have read the PDF reference and found following. With forms the nuance is there: the form object has transformation matrix and this matrix should be taken into account when calculating any coordinates of form's objects. In this case, you must use the following code to obtain the bounding box of the form's image object. Code:
int l, t, r, b;
Pdfium.FPDFPageObj_GetBBox(img.Handle, form.Matrix, out l, out t, out r, out b);
var imgBBox = new Rectangle(l, t, r - l, b - t);
Where the form - it is a PdfFormObjectthe img - it is a PdfImageObject from form.PageObjects collection
|
|
|
Originally Posted by: Paul Rayman  You have to calculate the offset of the target bounding box as a subtraction between the form object's bounding box and sub-object's bounding box. It worked for attached file, but not for this another file: test2.zip (448kb) downloaded 70 time(s).Coordinates are incorrect:  This is my current code: Code:
public const int DPI = 96;
public Rectangle BoundingBoxToRectangle(PdfPage page, Rectangle boundingBox, PdfFormObject form = null)
{
int width = Convert.ToInt32(page.Width / 72.0 * DPI);
int height = Convert.ToInt32(page.Height / 72.0 * DPI);
if (form != null)
{
boundingBox.Offset(form.BoundingBox.X - boundingBox.X, form.BoundingBox.Y - boundingBox.Y);
}
var top = page.PageToDevice(0, 0, width, height, PageRotate.Normal, boundingBox.Left, boundingBox.Top);
var bottom = page.PageToDevice(0, 0, width, height, PageRotate.Normal, boundingBox.Right, boundingBox.Bottom);
var rectangle = new Rectangle(top.X, top.Y, bottom.X - top.X, bottom.Y - top.Y);
if (rectangle.Width < 0)
{
rectangle.Width = -rectangle.Width;
rectangle.X -= rectangle.Width;
}
if (rectangle.Height < 0)
{
rectangle.Height = -rectangle.Height;
rectangle.Y -= rectangle.Height;
}
if (rectangle.Y < 0)
{
rectangle.Height = rectangle.Height + rectangle.Y;
rectangle.Y = 0;
}
if (rectangle.X < 0)
{
rectangle.Width = rectangle.Width + rectangle.X;
rectangle.X = 0;
}
if (rectangle.Bottom >= height)
{
rectangle.Height = rectangle.Height - (height - rectangle.Bottom + 1);
}
if (rectangle.Right >= width)
{
rectangle.Width = rectangle.Width - (width - rectangle.Right + 1);
}
return rectangle;
}
public Rectangle[] FindImagesRectangles(PdfPage page, PdfPageObjectsCollection objects, PdfFormObject form = null)
{
var rectangles = new List<Rectangle>();
foreach (var obj in objects)
{
if (obj is PdfImageObject)
{
rectangles.Add(BoundingBoxToRectangle(page, obj.BoundingBox, form));
}
else if (obj is PdfFormObject)
{
var parent = obj as PdfFormObject;
rectangles.AddRange(FindImagesRectangles(page, parent.PageObjects, parent));
}
}
return rectangles.ToArray();
}
public void GenerateImages(string filename)
{
PdfCommon.Initialize();
using (var document = PdfDocument.Load(filename))
{
for (var i = 0; i < document.Pages.Count; i++)
{
using (var page = document.Pages[i])
{
int width = Convert.ToInt32(page.Width / 72.0 * DPI);
int height = Convert.ToInt32(page.Height / 72.0 * DPI);
using (var bmp = new PdfBitmap(width, height, true))
{
bmp.FillRect(0, 0, bmp.Width, bmp.Height, Color.White);
page.Render(bmp, 0, 0, bmp.Width, bmp.Height, PageRotate.Normal, RenderFlags.FPDF_LCD_TEXT);
using (var image = new Bitmap(bmp.Image))
{
using (var g = Graphics.FromImage(image))
{
using (var pen = new Pen(Color.FromArgb(128, Color.Red), 4))
{
foreach (var rectangle in FindImagesRectangles(page, page.PageObjects))
{
g.DrawRectangle(pen, rectangle);
}
}
}
image.Save(Path.Combine(Path.GetDirectoryName(filename), string.Format("page-{0}.png", i+1)), ImageFormat.Png);
}
}
}
}
}
PdfCommon.Release();
}
|
|
|
You have to calculate the offset of the target bounding box as a subtraction between the form object's bounding box and sub-object's bounding box. Please look at following code Code:
var formBBox = obj.BoundingBox; // the BBox of an object on the page (form object)
var imgBBox = img.BoundingBox; //the BBbox of an object inside forms (found image object)
imgBBox.Offset(formBBox.X - imgBBox.X, formBBox.Y - imgBBox.Y);
//Translate and draw imgBBox
PageToDevice(...imgBBox...);
...
|
|
|
When the PdfImageObject is inside a PdfFormObject the BoundingBox not woking correctly. Using test.zip (453kb) downloaded 71 time(s). in GenerateImages("d:\\test.pdf"); With this code: Code:
public const int DPI = 96;
public void GenerateImages(string filename)
{
PdfCommon.Initialize();
using (var document = PdfDocument.Load(filename))
{
for (var i = 0; i < document.Pages.Count; i++)
{
using (var page = document.Pages[i])
{
int width = Convert.ToInt32(page.Width / 72.0 * DPI);
int height = Convert.ToInt32(page.Height / 72.0 * DPI);
using (var bmp = new PdfBitmap(width, height, true))
{
bmp.FillRect(0, 0, bmp.Width, bmp.Height, Color.White);
page.Render(bmp, 0, 0, bmp.Width, bmp.Height, PageRotate.Normal, RenderFlags.FPDF_LCD_TEXT);
using (var image = new Bitmap(bmp.Image))
{
using (var g = Graphics.FromImage(image))
{
using (var pen = new Pen(Color.FromArgb(128, Color.Red), 4))
{
foreach (var rectangle in FindImagesRectangles(page, page.PageObjects))
{
g.DrawRectangle(pen, rectangle);
}
}
}
image.Save(Path.Combine(Path.GetDirectoryName(filename), string.Format("page-{0}.png", i+1)), ImageFormat.Png);
}
}
}
}
}
PdfCommon.Release();
}
public Rectangle BoundingBoxToRectangle(PdfPage page, Rectangle boundingBox)
{
int width = Convert.ToInt32(page.Width / 72.0 * DPI);
int height = Convert.ToInt32(page.Height / 72.0 * DPI);
var top = page.PageToDevice(0, 0, width, height, PageRotate.Normal, boundingBox.Left, boundingBox.Top);
var bottom = page.PageToDevice(0, 0, width, height, PageRotate.Normal, boundingBox.Right, boundingBox.Bottom);
var rectangle = new Rectangle(top.X, top.Y, bottom.X - top.X, bottom.Y - top.Y);
if (rectangle.Width < 0)
{
rectangle.Width = -rectangle.Width;
rectangle.X -= rectangle.Width;
}
if (rectangle.Height < 0)
{
rectangle.Height = -rectangle.Height;
rectangle.Y -= rectangle.Height;
}
if (rectangle.Y < 0)
{
rectangle.Height = rectangle.Height + rectangle.Y;
rectangle.Y = 0;
}
if (rectangle.X < 0)
{
rectangle.Width = rectangle.Width + rectangle.X;
rectangle.X = 0;
}
if (rectangle.Bottom >= height)
{
rectangle.Height = rectangle.Height - (height - rectangle.Bottom + 1);
}
if (rectangle.Right >= width)
{
rectangle.Width = rectangle.Width - (width - rectangle.Right + 1);
}
return rectangle;
}
public Rectangle[] FindImagesRectangles(PdfPage page, PdfPageObjectsCollection objects)
{
var rectangles = new List<Rectangle>();
foreach (var obj in objects)
{
if (obj is PdfImageObject)
{
rectangles.Add(BoundingBoxToRectangle(page, obj.BoundingBox));
}
else if (obj is PdfFormObject)
{
var form = obj as PdfFormObject;
rectangles.AddRange(FindImagesRectangles(page, form.PageObjects));
}
}
return rectangles.ToArray();
}
It's generating this:
|