Fabric.js到Imagick(php)

Fabric.js到Imagick(php),php,fabricjs,imagick,Php,Fabricjs,Imagick,我正在使用一个定制的产品工具,该工具是围绕Fabric.js(FancyProductDesigner)构建的。我需要重新创建我用Fabric.js制作的东西(视图存储在数据库表中),并使用imagick重新制作,以便工厂打印/预览,而无需在服务器上存储每个高清图像。由于我们平均每天生产约400种定制产品,如果我存储每种产品,每天存储它们的空间约为160Mb,我们希望在购买后至少为客户存储90天 我已经设法使用PHP/Imagick重新创建了整个产品,除了一件事,如果有人在页面中添加文本,角度与

我正在使用一个定制的产品工具,该工具是围绕Fabric.js(FancyProductDesigner)构建的。我需要重新创建我用Fabric.js制作的东西(视图存储在数据库表中),并使用imagick重新制作,以便工厂打印/预览,而无需在服务器上存储每个高清图像。由于我们平均每天生产约400种定制产品,如果我存储每种产品,每天存储它们的空间约为160Mb,我们希望在购买后至少为客户存储90天

我已经设法使用PHP/Imagick重新创建了整个产品,除了一件事,如果有人在页面中添加文本,角度与Fabric.js传递的x/y坐标不匹配,我已经尝试使用originX/originY设置,但似乎没有任何影响

代码如下:

$print = new Imagick();
$print->setResolution(72, 72);
$print->newImage(894, 765, new ImagickPixel('#ffffff'));
foreach ($printData[0]->elements as $i => $object) {
  if($object->type == 'image'){
    $img = $object->source;
    $src = new Imagick($img);

    $size = $src->getImageGeometry();

    $resizeWidth = ($object->parameters->width * $object->parameters->scaleX);
    $resizeHeight = ($object->parameters->height * $object->parameters->scaleY);
    $src->resizeImage($resizeWidth, $resizeHeight, Imagick::FILTER_LANCZOS, 1);
    $sizeAfterResize = $src->getImageGeometry();

    if($object->parameters->flipX){
        $src->flopImage();
    }

    if($object->parameters->flipY){
        $src->flipImage();
    }

    if($object->parameters->angle > 0){
      $src->rotateImage(new ImagickPixel('transparent'), $object->parameters->angle);
      $sizeAfterRotate = $src->getImageGeometry();
    }

    if($object->parameters->fill != ''){
      $color = new ImagickPixel($object->parameters->fill);

      $opacityColor = new ImagickPixel("rgba(0, 0, 0, 1)");
      $src->colorizeImage($color, $opacityColor);
    }


    $src->evaluateImage(Imagick::EVALUATE_MULTIPLY, $object->parameters->opacity, Imagick::CHANNEL_ALPHA);

    $left = $object->parameters->left;
    $top = $object->parameters->top; 

    $left= ($left-($resizeWidth/2));
    $top = ($top-($resizeHeight/2));

    $print->compositeImage($src, Imagick::COMPOSITE_DEFAULT, $left, $top);
  } else {
    $draw = new ImagickDraw();
    $color = new ImagickPixel($object->parameters->fill);
    $foundFont = false;
    foreach($fonts as $name => $file){
        if($name == $object->parameters->fontFamily){
          $draw->setFont('fonts/custom/ttf/'.$file);
        $foundFont = true;
        continue;
      }
    }
    if(!$foundFont) $draw->setFont('fonts/'.$object->parameters->fontFamily.'.ttf');

    $draw->setFontSize($object->parameters->fontSize);
    //$draw->setFontSize(32);
    $draw->setFontWeight(($object->parameters->fontWeight == 'bold') ? 600 : 100 );
    $draw->setFontStyle(0);
    $draw->setFillColor($color);
    $draw->setStrokeAntialias(true);
    $draw->setTextAntialias(true);
    //$draw->setGravity(Imagick::GRAVITY_CENTER);
    $draw->setTextAlignment(Imagick::ALIGN_CENTER);


    if($object->parameters->stroke){
      $draw->setStrokeColor($object->parameters->stroke);
      $draw->setStrokeWidth($object->parameters->strokeWidth);
      $draw->setStrokeAntialias(true);  //try with and without
    }

    $metrics = $print->queryFontMetrics($draw, $object->parameters->text);

    $realleft = round($object->parameters->left);
    $realtop = round($object->parameters->top);

    $top = $realtop;
    $left = $realleft;

    $print2 = new Imagick();
    $print2->setResolution(72, 72);

    $print2->newImage(894, 765, new ImagickPixel('#00000000'));
    $print2->setImageVirtualPixelMethod( imagick::VIRTUALPIXELMETHOD_BACKGROUND );

    $print2->annotateImage($draw, $left, $top, $object->parameters->angle, $object->parameters->text);

    if($object->parameters->flipX == 1) $print2->flopImage(); // x
    if($object->parameters->flipY == 1) $print2->flipImage(); // y

    $print2->trimImage(0);
    $print2->setImagePage(0, 0, 0, 0); 

    $d = $print2->getImageGeometry();

    $left-=($d['width']/2);
    $top-=($d['height']/2);

    $print->compositeImage($print2, Imagick::COMPOSITE_DEFAULT, $left, $top);
  }
}
我必须将文本添加到一个图像中,然后将该图像添加到元素中,因为我无法找到一些文本的特性,例如触发器和触发器。如果文本元素上没有角度,则会在Fabric.js和Imagick之间完美地重新创建图像

期望值

现实

如果您查看它,您会发现旋转会导致文本位于Imagick和Fabric.js之间的不同位置。与其他字体相比,此问题在某些字体上更为明显

我可能错过了一些很容易的东西,但我就是看不见,这让我很生气。目前,我刚刚禁用了在设计工具上旋转文本的功能,但是这不是一个完美的解决方案


只是为了澄清这不是的副本,它不会解决添加文本时的角度问题。

即使它不是副本,我仍然建议抓取SVG并直接使用ImageMagick进行转换。这将允许您开始识别代码错误的确切位置。我不明白您的意思,我使用ImageMagick进行转换,角度是唯一存在问题的部分,显然ImageMagick角度文本的方式与Fabric.js和/或Canvas的方式不同。即使它不是重复的,我仍然建议抓取SVG并直接使用ImageMagick进行转换。这将允许您开始识别代码错误的确切位置。我不明白您的意思,我使用ImageMagick进行转换,角度是唯一存在问题的部分,显然ImageMagick角度文本的方式与Fabric.js和/或Canvas的方式不同。