Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP ImageMagick Plane2Cylinder Perspective

I am trying to change the perspective of the Plane2Cylinder distortion in ImageMagick via PHP.

To help explain what I'm looking for, I've created this graphic:

Sample of perspective

You can see that the lower part of the red block has a greater radius than the top part, as if you were viewing this from above center.

I have tried the optional center_x/y fields:

$label->distortImage(\Imagick::DISTORTION_PLANE2CYLINDER, [28,0,100], true);

With various settings between 0 and 1000 on each x and y, with zero results.

Anyone have any insights or hints? I've search thoroughly, but can't find anything relevent.

like image 990
Luke Pittman Avatar asked Nov 16 '25 00:11

Luke Pittman


2 Answers

I haven't fount solution with the DISTORTION_PLANE2CYLINDER but just as an idea that a hardcore perspective may reduce the strength of difference and maybe become also a point for further distortions for eg. Circular and Radial Distortion Methods (Arc).

enter image description here

plus

convert img.png \
-matte \
-virtual-pixel transparent \
-distort Perspective '200,0,0,0 100,700,100,700 700,700,700,700 600,0,800,0 ' \
img1.png

enter image description here

May give you desired radius on top and bottom.

like image 79
Jimmix Avatar answered Nov 17 '25 19:11

Jimmix


Programming solution

I solved this with the following code - works like a charm and delivers the right result. Be aware, the angle also depends on the distance of the viewer, not only on the eye level.

public function renderCyclinderToPlane()
{
    //http://www.imagemagick.org/Usage/distorts/#cylinder2plane
    $imagick = new \Imagick(realpath($this->distortImageControl->getImagePath()));
    $points = array(
        70, //fov_angle,
        //center_x,y,
        //fov_output,
        //dest_center_x,y
    );
    $imagick->setImageBackgroundColor("#fad888");
    $imagick->setImageVirtualPixelMethod(\Imagick::VIRTUALPIXELMETHOD_BACKGROUND);
    $imagick->distortImage(\Imagick::DISTORTION_CYLINDER2PLANE, $points, true);
    header("Content-Type: image/jpeg");
    echo $imagick;
}

References / Credits go to:

  • https://phpimagick.com/
  • https://github.com/Imagick/ImagickDemos
  • https://github.com/Imagick/ImagickDemos/blob/def2cedc27d74e9ddd4a638154651dd3924ade11/src/ImagickDemo/Imagick/distortImage.php

Also see: How can I apply a pincushion distortion effect on a svg image (in order to read a qr code on round surface reliably)?

Non-programming alternative

If you just want to put an qr code on a glass/jar/bottle, put it on the top or bottom.

like image 21
BogisW Avatar answered Nov 17 '25 18:11

BogisW