简体   繁体   中英

Convert x,y coordinates after resize in PHP

This is quite a complicated and brain busting question, so please read carefully and don't just skim through. Thanks!

I'm extracting images from a PDF file and rebuilding the page image. It's all working except I can't get the coordinates just right for placing the little images over the larger background image.

I start with something like this:

$page_width = 1000;
$page_height = 1500;
$back_img_x = 5
$back_img_y = 8
$back_img_width = 990;
$back_img_height = 1501;
$back_img_truewidth = 3000;
$back_img_trueheight = 4000;
$little_img_x = 550;
$little_img_y = 250;
$little_img_width = 200;
$little_img_height = 100;

Now to explain, the back image is not necessarily the same size as the page, which means it's being scaled, it is also not necessarily position at 0,0 which is due to whoever the stupid person was who made the PDF in the first place (or which application.)

What I now do is ignore the page size and try to map the little image onto the back image in the correct position after trimming the back image.

So lots of complicated things are now done to the back image, which results in the following:

$trimleft = 100;
$trimright = 100;
$trimtop = 40;
$trimbottom = 120;
$margin_x = 50;
$margin_y = 35
$offset_x = 0;
$offset_y = 90;

The back image is then correctly trimmed and placed upon a new canvas like this:

$fullwidth=($trimright-$trimleft)+($margin_x*2);
$fullheight=($trimbottom-$trimtop)+($margin_y*2);
$trimmed=imagecreate($fullwidth,$fullheight);
imagefill($trimmed,0,0,imagecolorallocate($trimmed,255,255,255)); // make white
imagecopy($trimmed,$image,$margin_x+$offset_x,$margin_y+$offset_y,$trimleft,$trimtop,$trimright-$trimleft,$trimbottom-$trimtop);

So far so good...

Now I want to find the x, y, width & height of the little image to be in the correct position over the background image.

I do this:

$little_img_width=($little_img_width/$back_img_width);
$little_img_height=($little_img_height/$back_img_height);
$little_img_x=(($little_img_x-$back_img_x)/$back_img_width)*$back_img_truewidth;
$little_img_y=(($little_img_y-$back_img_y)/$back_img_height)*$back_img_trueheight;

$little_img_width*=($back_img_truewidth/$fullwidth);
$little_img_height*=($back_img_trueheight/$fullheight);
$little_img_x=($little_img_x-$trimleft+$margin_x+$offset_x)/$fullwidth;
$little_img_y=($little_img_y-$trimtop+$margin_y+$offset_y)/$fullheight;

That should give me the correct x, y, width & height of the little image, correctly positioned and sized on the background image (in percentage where 0 is far left and 1 is far right, etc.) The width/height are correct but the coordinates are very slightly off. It is the y coordinate that is too low on the page by about 5%. Note that $offset_x is 0, which would suggest that the problem lies with the offset variables (since $offset_x is 0, it is not showing an positioning error for x axis, only y axis).

I've been staring at these values for days and rewritten them all a few times. This time it all looks perfect to me. I don't understand what is still wrong.

If I'm understanding the math correctly, here's what's happening:

You have $fullwidth and $fullheight which are the width and height that the image will be occupying on your canvas.

You then multiply the smaller image's width and height by the ratio of its size to the full size in the original, unprocessed image. Which is correct.

However, when you are calculating $little_img_x and $little_img_y , you are doing this:

$little_img_x=(($little_img_x-$back_img_x)/$back_img_width)*$back_img_truewidth;
$little_img_y=(($little_img_y-$back_img_y)/$back_img_height)*$back_img_trueheight;

This ends up returning an awkwardly arbitrary number (something like 150 for x and 100 for y), which I can't find any possible use for.

You then go on and use that value to calculate the new x and y for the little image, which would result in another arbitrary number which shows no purpose.

I propose a new approach where $little_img_x and $little_img_y are calculated as follows:

$little_img_x = ($little_img_x/$back_img_x)*$fullwidth + (($little_img_x-$trimleft+$margin_x+$offset_x) / $fullwidth)
$little_img_y = ($little_img_y/$back_img_y)*fullheight + (($little_img_y-$trimtop+$margin_y+$offset_y)/ $fullheight)

Basically, we take the little image's original x, get its ratio to the background's x, multiply it by the new width to get the presented x, and then add all of the offset processing. We do the same thing with y.

I have no idea if this works, but I hope it does. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM