• <bdo id='ShzFi'></bdo><ul id='ShzFi'></ul>
    <legend id='ShzFi'><style id='ShzFi'><dir id='ShzFi'><q id='ShzFi'></q></dir></style></legend>
  • <small id='ShzFi'></small><noframes id='ShzFi'>

    1. <i id='ShzFi'><tr id='ShzFi'><dt id='ShzFi'><q id='ShzFi'><span id='ShzFi'><b id='ShzFi'><form id='ShzFi'><ins id='ShzFi'></ins><ul id='ShzFi'></ul><sub id='ShzFi'></sub></form><legend id='ShzFi'></legend><bdo id='ShzFi'><pre id='ShzFi'><center id='ShzFi'></center></pre></bdo></b><th id='ShzFi'></th></span></q></dt></tr></i><div id='ShzFi'><tfoot id='ShzFi'></tfoot><dl id='ShzFi'><fieldset id='ShzFi'></fieldset></dl></div>

        <tfoot id='ShzFi'></tfoot>
      1. 如何使用 PHP ImageMagic/Imagick 从 JSON/数据数组(宽度、高度、x、y、天使)创建大型(高质

        时间:2024-08-10
        <i id='ZVGU2'><tr id='ZVGU2'><dt id='ZVGU2'><q id='ZVGU2'><span id='ZVGU2'><b id='ZVGU2'><form id='ZVGU2'><ins id='ZVGU2'></ins><ul id='ZVGU2'></ul><sub id='ZVGU2'></sub></form><legend id='ZVGU2'></legend><bdo id='ZVGU2'><pre id='ZVGU2'><center id='ZVGU2'></center></pre></bdo></b><th id='ZVGU2'></th></span></q></dt></tr></i><div id='ZVGU2'><tfoot id='ZVGU2'></tfoot><dl id='ZVGU2'><fieldset id='ZVGU2'></fieldset></dl></div>

        1. <tfoot id='ZVGU2'></tfoot>
            <tbody id='ZVGU2'></tbody>

              1. <small id='ZVGU2'></small><noframes id='ZVGU2'>

                  <bdo id='ZVGU2'></bdo><ul id='ZVGU2'></ul>
                • <legend id='ZVGU2'><style id='ZVGU2'><dir id='ZVGU2'><q id='ZVGU2'></q></dir></style></legend>

                  本文介绍了如何使用 PHP ImageMagic/Imagick 从 JSON/数据数组(宽度、高度、x、y、天使)创建大型(高质量 300dpi)图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  我使用 FabricJs 在 Canvas 上创建了一个包含一些图片和文本的设计 (270x470),然后我导出所有图片/通过fabricJS的canvas.toJSON()方法以JSON格式的文本信息现在我需要使用Imagick在PHP中的高质量(2790x4560)图像上重新绘制该设计.

                  I created a design (270x470) with some pictures and text on Canvas using FabricJs then i export all pictures/text information in JSON format by fabricJS's canvas.toJSON() method And Now i need to Re-Draw that design on a High Quality (2790x4560) image in PHP using Imagick.

                  上述设计的 JSON dataArray 包含所有对象的信息,如大小、位置、角度等.

                  JSON dataArray for above design which contains all object's information like size,position,angle etc..

                  {
                  "width": "2790",
                  "height": "4560",
                  "json_data": {
                      "objects": [{
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "5",
                              "top": "105",
                              "width": "260",
                              "height": "260",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "0",
                              "opacity": "1",
                              "src": "http:\example.com/images/098f20be9fb7b66d00cb573acc771e99.JPG",
                          }, {
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "5",
                              "top": "229.5",
                              "width": "260",
                              "height": "11",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "0",
                              "opacity": "1",
                              "src": "http:\example.com/images/aeced466089d875a7c0dc2467d179e58.png",
                          }, {
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "51.07",
                              "top": "135.58",
                              "width": "260",
                              "height": "11",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "47.41",
                              "opacity": "1",
                              "src": "http:\example.com/images/910ce024d984b6419d708354bf3641a3.png",
                          }, {
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "139.71",
                              "top": "104.97",
                              "width": "260",
                              "height": "11",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "89.65",
                              "opacity": "1",
                              "src": "http:\example.com/images/88e096a82e5f8a503a71233addaff64c.png",
                          }, {
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "230.78",
                              "top": "146.93",
                              "width": "260",
                              "height": "11",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "134.98",
                              "src": "http:\example.com/images/d2c0ec738c1fec827381cfeb600bd87d.png",
                          }, {
                              "type": "image",
                              "originX": "left",
                              "originY": "top",
                              "left": "265.01",
                              "top": "240.19",
                              "width": "260",
                              "height": "11",
                              "scaleX": "1",
                              "scaleY": "1",
                              "angle": "179.86",
                              "opacity": "1",
                              "src": "http:\example.com/images/3f0bc771261860d917e0ad6d09cb2064.png",
                          }],
                      "background": "#FF00FF"
                  }}
                  

                  这里是我的代码片段,用于使用 JSON dataArray 在 PHP 中生成高质量图像

                  error_reporting(E_ALL | E_STRICT);
                  
                  try {
                    $id = $_GET['id']; // Design ID
                  
                    define('DS', DIRECTORY_SEPARATOR);
                  
                    $jsonDir = dirname(__FILE__) . DS . 'media' . DS . 'designs';
                    $printData = json_decode(file_get_contents($jsonDir . DS . $id . '.json'));
                  
                    } catch (Exception $e) {
                       echo $e->getMessage();
                    }
                  
                  try {
                     $print = new Imagick();
                     $print->setResolution(300, 300);
                     $background = (empty($printData->json_data->background)) ? 'transparent' : $printData->json_data->background;
                     $print->newImage($printData->width, $printData->height, new ImagickPixel($background));
                  
                     $print->setImageFormat('png32');
                     $print->setImageUnits(imagick::RESOLUTION_PIXELSPERCENTIMETER);
                  } catch (Exception $e) {
                     echo $e->getMessage();
                  }
                  
                  // Re-Scaling each Image/Text for Larger Canvas/Image 
                  foreach ($printData->json_data->objects as $i => $object) {
                  
                     if ($object->type == 'image') {
                          addImage($object, $print, $printData);
                     } else {
                          addText($object, $print, $printData);
                     }
                  }
                  
                  
                  try {
                     // Saving High Quality Image in (300 dpi)
                     $fileDir = dirname(__FILE__) . DS . 'media' . DS . 'prints';
                  
                     if (!file_exists($fileDir) || !is_dir($fileDir)) {
                         if (!mkdir($fileDir))
                             die("Could not create directory: {$fileDir}
                  ");
                     }
                     $saved = $print->writeimage($fileDir . DS . $id . '.png');
                     header('Content-type: image/png');
                     echo $print;
                   } catch (Exception $e) {
                        echo $e->getMessage();
                   }
                  

                  <小时>

                  addImage();

                  function addImage($object, $print, $printData) {
                  
                      try {
                          $widthScale = ($printData->width / 270);
                          $heightScale = ($printData->height / 470);
                          $fileDir = dirname(__FILE__) . DS . 'media' . DS . 'original' . DS;
                          $src = new Imagick($fileDir . basename($object->src));
                  
                          $size = $src->getImageGeometry();
                  
                          $resizeWidth = ($object->width * $object->scaleX) * $widthScale;
                          $resizeHeight = ($object->height * $object->scaleY) * $heightScale;
                          $src->resizeImage($resizeWidth, $resizeHeight, Imagick::FILTER_LANCZOS, 1);
                          $sizeAfterResize = $src->getImageGeometry();
                  
                          $src->rotateImage(new ImagickPixel('none'), $object->angle);
                          $sizeAfterRotate = $src->getImageGeometry();
                  
                  
                          if (!$object->angle) {
                              $left = $object->left * $widthScale;
                              $top = $object->top * $heightScale;
                          } else {
                  
                              switch ($object->angle) {
                                  case $object->angle > 315:
                                      $left = ($object->left * $widthScale);
                                      $top = ($object->top * $heightScale);
                                      break;
                                  case $object->angle > 270:
                                      $left = ($object->left * $widthScale);
                                      $top = ($object->top * $heightScale);
                  
                                      break;
                                  case $object->angle > 225:
                                      $left = ($object->left * $widthScale);
                                      $top = ($object->top * $heightScale);
                                      break;
                                  case $object->angle > 180:
                                      $left = ($object->left * $widthScale);
                                      $top = ($object->top * $heightScale);
                                      break;
                                  case $object->angle > 135:
                                      $left = ($object->left * $widthScale);
                                      $top = ($object->top * $heightScale);
                                      break;
                                  case $object->angle > 90:
                                      $left = ($object->left * $heightScale) - ($sizeAfterRotate['width'] / 2);
                                      $top = ($object->top * $heightScale) - ($sizeAfterRotate['width'] / 2);
                                      break;
                                  case $object->angle > 45:
                                      $left = ($object->left * $widthScale) - $size['height'] * $widthScale;
                                      $top = ($object->top * $heightScale) - $size['height'] * $heightScale;
                                      break;
                  
                                  default:
                                      $left = $object->left * $widthScale;
                                      $top = $object->top * $heightScale;
                  
                                      break;
                              }
                          }
                  
                          $print->compositeImage($src, Imagick::COMPOSITE_DEFAULT, $left, $top);
                      } catch (Exception $e) {
                          echo $e->getMessage();
                      }
                  }
                  

                  <小时>

                  我的输出结果 (90%) 存在上述解决方案,但我们可以看到一些图像(蓝色数字线)没有放置在应该看起来像第一个设计图像的确切位置


                  My Output results (90%) is there with above solution, but as we can see some image (blue number line) doesn't place at exact position which should look like first design image

                  基本上我想做的是,在循环中调用 addImage 方法进行缩放 - 旋转 - 将每个图像定位在 Print Image(300DPi) 上

                  Basically what i am trying to do is, " Inside a Loop calling an addImage Method for scale - rotate - position each image on Print Image(300DPi)

                  我不确定在 Imagick 中为图像旋转后获得精确偏移量(新的 x,y 坐标/位置/左上)缺少什么或者我在 Scale 之后旋转对象然后组合

                  i am not sure what i am missing to get exact offset (new x,y coordinates/position/Left-Top ) after Rotation for an image in Imagick or i am Rotating object after Scale then compose

                  或可能是 Math.PI 之类的数学公式 :)

                  or May be A Math Formula like Math.PI :)

                  问题是:如何根据 Scale after Rotation Degree/Angle 计算新的偏移/位置?

                  我希望发布的片段对每个人都有用.

                  I hope posted snippet are useful for everyone.

                  推荐答案

                  我这里有一个解决方案,可能会帮助像我这样的人

                  Here I get a solution, may be it will help others like for me

                  <?php
                  
                  // AZinkey
                  ini_set('memory_limit', '1024M'); // may be need increase memory size
                  ini_set('display_errors', 1); // enable error display
                  error_reporting(E_ALL); // show all type errors
                  
                  $id = $_GET['id'];
                  $file = $id . ".json"; // json file e.g. 1234.json
                  $printData = json_decode(file_get_contents($file));
                  
                  $mask = "mask.png"; // a image (4395x4395) which contains 2669x4395 black fill in center
                  $maskImg = new Imagick($mask);
                  $d = $maskImg->getImageGeometry();
                  
                  $maskWidth = $d['width'];
                  $maskHeight = $d['height'];
                  
                  // Then reduce any list of integer
                  $cd = array_reduce(array($maskWidth, 400), 'gcd');
                  $r1 = $maskWidth / $cd;
                  $r2 = 400 / $cd;
                  
                  $newPrintData['r1'] = $r1;
                  $newPrintData['r2'] = $r2;
                  
                  
                  try {
                      $print = new Imagick();
                      $print->setResolution(300, 300);
                      $background = (empty($printData->json_data->background)) ? 'transparent' : $printData->json_data->background;
                      $print->newImage($maskWidth, $maskHeight, new ImagickPixel($background));
                  
                      $print->setImageMatte(TRUE);
                      $print->setImageFormat('png32');
                      $print->setImageUnits(imagick::RESOLUTION_PIXELSPERCENTIMETER);
                  } catch (Exception $e) {
                      echo $e->getMessage();
                  }
                  
                  // create two array for store text & images information separately 
                  $imageObjects = $textObjects = [];
                  
                  foreach ($printData->json_data->objects as $object) {
                      if ($object->type == 'image') {
                          $imageObjects[] = $object;
                      } else if ($object->type == 'text') {
                          $imageObjects[] = $object;
                      }
                  }
                  foreach ($imageObjects as $object) {
                      addImageToLarge($object, $print, $printData, $newPrintData);
                  }
                  
                  foreach ($imageObjects as $object) {
                      addTextToLarge($object, $print, $printData, $newPrintData);
                  }
                  try {
                      $print->setImageFormat('png');
                      $saveFile = $id . "_print.json"; // save large image _print.png
                      file_put_contents($saveFile, $print);
                  } catch (Exception $e) {
                      echo $e->getMessage();
                      exit();
                  }
                  
                  function addImageToLarge($object, $print, $printData, $newPrintData) {
                      try {
                          $src = new Imagick($object->src);
                          $size = $src->getImageGeometry();
                          $resizeWidth = changeDpi(scale($object->width, $newPrintData['r1'], $newPrintData['r2']) * $object->scaleX);
                          $resizeHeight = changeDpi(scale($object->height, $newPrintData['r1'], $newPrintData['r2']) * $object->scaleY);
                  
                          $src->resizeImage($resizeWidth, $resizeHeight, Imagick::FILTER_LANCZOS, 1);
                          $sizeAfterResize = $src->getImageGeometry();
                  
                          $src->rotateImage(new ImagickPixel('none'), $object->angle);
                          $sizeAfterRotate = $src->getImageGeometry();
                  
                          $left = $object->left < 0 ? -1 * abs(changeDpi(scale($object->left, $newPrintData['r1'], $newPrintData['r2']))) : changeDpi(scale($object->left, $newPrintData['r1'], $newPrintData['r2']));
                          $top = $object->top < 0 ? -1 * abs(changeDpi(scale($object->top, $newPrintData['r1'], $newPrintData['r2']))) : changeDpi(scale($object->top, $newPrintData['r1'], $newPrintData['r2']));
                  
                          $print->compositeImage($src, Imagick::COMPOSITE_OVER, $left, $top);
                      } catch (Exception $e) {
                          echo $e->getMessage();
                          exit();
                      }
                  }
                  
                  function addTextToLarge($object, $print, $printData, $newPrintData) {
                      $fnt['Times New Roman'] = "font/times_6.ttf";
                      $fnt['Arial'] = "font/arial_8.ttf";
                      $fnt['Arial Black'] = "font/ariblk_8.ttf";
                      $fnt['Comic Sans MS'] = "font/comic_5.ttf";
                      $fnt['Courier New'] = "font/cour_5.ttf";
                      $fnt['Georgia'] = "font/georgia_5.ttf";
                      $fnt['Impact'] = "font/impact_7.ttf";
                      $fnt['Lucida Console'] = "font/lucon_3.ttf";
                      $fnt['Lucida Sans Unicode'] = "font/l_4.ttf";
                      $fnt['Palatino Linotype'] = "font/pala_7.ttf";
                      $fnt['Tahoma'] = "font/tahoma_3.ttf";
                      $fnt['Trebuchet MS'] = "font/trebuc_3.ttf";
                      $fnt['Verdana'] = "font/verdana_5.ttf";
                  
                      try {
                          $line_height_ratio = $object->lineHeight;
                          $resizeWidth = changeDpi(scale($object->width, $newPrintData['r1'], $newPrintData['r2']) * $object->scaleX);
                          $resizeHeight = changeDpi(scale($object->height, $newPrintData['r1'], $newPrintData['r2']) * $object->scaleY);
                  
                          $print2 = new Imagick();
                          $print2->setResolution(300, 300);
                          $print2->newImage($resizeWidth, $resizeHeight, "transparent");
                          $print2->setImageVirtualPixelMethod(imagick::VIRTUALPIXELMETHOD_BACKGROUND);
                          $print2->setImageFormat('png32');
                          $print2->setImageUnits(imagick::RESOLUTION_PIXELSPERCENTIMETER);
                  
                          // Instantiate Imagick utility objects
                          $draw = new ImagickDraw();
                          $color = new ImagickPixel($object->fill);
                  
                          //$starting_font_size = 100*1.33;
                          $font_size = (($object->fontSize * $resizeWidth) / $object->width);
                  
                          $draw->setFontWeight(($object->fontWeight == 'bold') ? 600 : 100 );
                          $draw->setFontStyle(0);
                          $draw->setFillColor($color);
                  
                          // Load Font 
                          //$font_size = $starting_font_size;
                          $draw->setFont($fnt[$object->fontFamily]);
                          $draw->setFontSize($font_size);
                  
                          $draw->setTextAntialias(true);
                          $draw->setGravity(Imagick::GRAVITY_CENTER);
                  
                          if ($object->stroke) {
                              $draw->setStrokeColor($object->stroke);
                              $draw->setStrokeWidth($object->strokeWidth);
                              $draw->setStrokeAntialias(true);  //try with and without
                          }
                  
                          $total_height = 0;
                  
                          // Run until we find a font size that doesn't exceed $max_height in pixels
                          while (0 == $total_height || $total_height > $resizeHeight) {
                              if ($total_height > 0) {
                                  $font_size--; // we're still over height, decrement font size and try again
                              }
                              $draw->setFontSize($font_size);
                  
                              // Calculate number of lines / line height
                              // Props users Sarke / BMiner: http://stackoverflow.com/questions/5746537/how-can-i-wrap-text-using-imagick-in-php-so-that-it-is-drawn-as-multiline-text
                              $words = preg_split('%s%', $object->text, -1, PREG_SPLIT_NO_EMPTY);
                              $lines = array();
                              $i = 0;
                              $line_height = 0;
                  
                              while (count($words) > 0) {
                                  $metrics = $print2->queryFontMetrics($draw, implode(' ', array_slice($words, 0, ++$i)));
                                  $line_height = max($metrics['textHeight'], $line_height);
                  
                                  if ($metrics['textWidth'] > $resizeWidth || count($words) < $i) {
                                      $lines[] = implode(' ', array_slice($words, 0, --$i));
                                      $words = array_slice($words, $i);
                                      $i = 0;
                                  }
                              }
                  
                              $total_height = count($lines) * $line_height * $line_height_ratio;
                  
                              if ($total_height > 0) {
                  
                              }
                          }
                          // Writes text to image
                          $x_pos = 0;
                          $y_pos = 0;
                  
                          for ($i = 0; $i < count($lines); $i++) {
                              $print2->annotateImage($draw, $x_pos, $y_pos + ($i * $line_height * $line_height_ratio), $object->angle, $lines[$i]);
                          }
                  
                          if ($object->flipX == 1)
                              $print2->flopImage(); // x
                          if ($object->flipY == 1)
                              $print2->flipImage(); // y
                  
                          $print2->trimImage(0);
                          $print2->setImagePage(0, 0, 0, 0);
                  
                          $print2->resizeImage($resizeWidth, 0, Imagick::FILTER_CATROM, 0.9, false);
                  
                          $left = $object->left < 0 ? -1 * abs(changeDpi(scale($object->left, $newPrintData['r1'], $newPrintData['r2']))) : changeDpi(scale($object->left, $newPrintData['r1'], $newPrintData['r2']));
                          $top = $object->top < 0 ? -1 * abs(changeDpi(scale($object->top, $newPrintData['r1'], $newPrintData['r2']))) : changeDpi(scale($object->top, $newPrintData['r1'], $newPrintData['r2']));
                  
                          $print->compositeImage($print2, Imagick::COMPOSITE_OVER, $left, $top);
                  
                          //header("Content-Type: image/png");
                          //echo $print2;exit;
                      } catch (Exception $e) {
                          echo $e->getMessage();
                          exit();
                      }
                  }
                  
                  //The greatest common divisor (GCD) 
                  function gcd($a, $b) {
                      return $b ? gcd($b, $a % $b) : $a;
                  }
                  
                  function changeDpi($px) {
                      //return ($px/96)*300;
                      return $px;
                  }
                  
                  function scale($px, $r1, $r2) {
                      return $px * $r1 / $r2;
                  }
                  

                  这篇关于如何使用 PHP ImageMagic/Imagick 从 JSON/数据数组(宽度、高度、x、y、天使)创建大型(高质量 300dpi)图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:图片在上传时自动旋转 下一篇:使用 JMS Serializer 时禁用 Doctrine 2 延迟加载?

                  相关文章

                • <tfoot id='djwcb'></tfoot>
                    • <bdo id='djwcb'></bdo><ul id='djwcb'></ul>
                    <i id='djwcb'><tr id='djwcb'><dt id='djwcb'><q id='djwcb'><span id='djwcb'><b id='djwcb'><form id='djwcb'><ins id='djwcb'></ins><ul id='djwcb'></ul><sub id='djwcb'></sub></form><legend id='djwcb'></legend><bdo id='djwcb'><pre id='djwcb'><center id='djwcb'></center></pre></bdo></b><th id='djwcb'></th></span></q></dt></tr></i><div id='djwcb'><tfoot id='djwcb'></tfoot><dl id='djwcb'><fieldset id='djwcb'></fieldset></dl></div>

                    <legend id='djwcb'><style id='djwcb'><dir id='djwcb'><q id='djwcb'></q></dir></style></legend>

                      <small id='djwcb'></small><noframes id='djwcb'>