Пример #1
0
 function encode_gmagick($ps_filepath, $ps_output_path, $pa_options)
 {
     if (!($magick = $this->mimetype2magick[$pa_options["output_mimetype"]])) {
         $this->error = "Invalid output format";
         return false;
     }
     #
     # Open image
     #
     try {
         $h = new Gmagick($ps_filepath);
         $h->setimageindex(0);
         // force use of first image in multi-page TIFF
     } catch (Exception $e) {
         $this->error = "Couldn't open image {$ps_filepath}";
         return false;
     }
     if (function_exists('exif_read_data')) {
         if (is_array($va_exif = @exif_read_data($ps_filepath, 'EXIF', true, false))) {
             if (isset($va_exif['IFD0']['Orientation'])) {
                 $vn_orientation = $va_exif['IFD0']['Orientation'];
                 switch ($vn_orientation) {
                     case 3:
                         $h->rotateimage("#FFFFFF", 180);
                         break;
                     case 6:
                         $h->rotateimage("#FFFFFF", 90);
                         break;
                     case 8:
                         $h->rotateimage("#FFFFFF", -90);
                         break;
                 }
             }
         }
     }
     $h->setimagetype(Gmagick::IMGTYPE_TRUECOLOR);
     if (!$h->setimagecolorspace(Gmagick::COLORSPACE_RGB)) {
         $this->error = "Error during RGB colorspace transformation operation";
         return false;
     }
     $va_tmp = $h->getimagegeometry();
     $image_width = $va_tmp['width'];
     $image_height = $va_tmp['height'];
     if ($image_width < 10 || $image_height < 10) {
         $this->error = "Image is too small to be output as Tilepic; minimum dimensions are 10x10 pixels";
         return false;
     }
     if ($pa_options["scale_factor"] != 1) {
         $image_width *= $pa_options["scale_factor"];
         $image_height *= $pa_options["scale_factor"];
         if (!$h->resizeimage($image_width, $image_height, Gmagick::FILTER_CUBIC, $pa_options["antialiasing"])) {
             $this->error = "Couldn't scale image";
             return false;
         }
     }
     #
     # How many layers to make?
     #
     if (!$pa_options["layers"]) {
         $sw = $image_width * $pa_options["layer_ratio"];
         $sh = $image_height * $pa_options["layer_ratio"];
         $pa_options["layers"] = 1;
         while ($sw >= $pa_options["tile_width"] || $sh >= $pa_options["tile_height"]) {
             $sw = ceil($sw / $pa_options["layer_ratio"]);
             $sh = ceil($sh / $pa_options["layer_ratio"]);
             $pa_options["layers"]++;
         }
     }
     #
     # Cut image into tiles
     #
     $tiles = 0;
     $layer_list = array();
     $base_width = $image_width;
     $base_height = $image_height;
     if ($this->debug) {
         print "BASE {$base_width} x {$base_height} \n";
     }
     for ($l = $pa_options["layers"]; $l >= 1; $l--) {
         $x = $y = 0;
         $wx = $pa_options["tile_width"];
         $wy = $pa_options["tile_height"];
         if ($this->debug) {
             print "LAYER={$l}\n";
         }
         if ($l < $pa_options["layers"]) {
             $image_width = ceil($image_width / $pa_options["layer_ratio"]);
             $image_height = ceil($image_height / $pa_options["layer_ratio"]);
             if ($this->debug) {
                 print "RESIZE layer {$l} TO {$image_width} x {$image_height} \n";
             }
             if (!$h->resizeimage($image_width, $image_height, Gmagick::FILTER_CUBIC, $pa_options["antialiasing"])) {
                 $this->error = "Couldn't scale image";
                 return false;
             }
         }
         $i = 0;
         $layer_list[] = array();
         while ($y < $image_height) {
             $slice = clone $h;
             try {
                 $slice->cropimage($wx, $wy, $x, $y);
                 $slice->setcompressionquality($pa_options["quality"]);
             } catch (Exception $e) {
                 $this->error = "Couldn't create tile";
                 return false;
             }
             if (!$slice->setimageformat($magick)) {
                 $this->error = "Tile conversion failed: {$reason}; {$description}";
                 return false;
             }
             # --- remove color profile (saves lots of space)
             $layer_list[sizeof($layer_list) - 1][] = $slice->getImageBlob();
             $slice->destroy();
             $x += $pa_options["tile_width"];
             if ($x >= $image_width) {
                 $y += $pa_options["tile_height"];
                 $x = 0;
             }
             $i++;
             $tiles++;
         }
         if ($this->debug) {
             print "OUTPUT {$tiles} TILES FOR LAYER {$l} : {$image_width} x {$image_height}\n";
         }
     }
     $h->destroy();
     #
     # Write Tilepic format file
     #
     if ($this->debug) {
         print "WRITING FILE...";
     }
     if ($fh = fopen($ps_output_path . ".tpc", "w")) {
         # --- attribute list
         $attribute_list = "";
         $attributes = 0;
         if (isset($pa_options["attributes"]) && is_array($pa_options["attributes"])) {
             $pa_options["attributes"]["mimeType"] = $pa_options["output_mimetype"];
         } else {
             $pa_options["attributes"] = array("mimeType" => $pa_options["output_mimetype"]);
         }
         foreach ($pa_options["attributes"] as $k => $v) {
             $attribute_list .= "{$k}={$v}";
             $attributes++;
         }
         if ($this->debug) {
             print "header OK;";
         }
         # --- header
         if (!fwrite($fh, "TPC\n")) {
             $this->error = "Could not write Tilepic signature";
             return false;
         }
         if (!fwrite($fh, pack("NNNNNNnnNN", 40, $base_width, $base_height, $pa_options["tile_width"], $pa_options["tile_height"], $tiles, $pa_options["layers"], $pa_options["layer_ratio"], strlen($attribute_list), $attributes))) {
             $this->error = "Could not write Tilepic header";
             return false;
         }
         # --- offset table
         $offset = 44 + $tiles * 4;
         for ($i = sizeof($layer_list) - 1; $i >= 0; $i--) {
             for ($j = 0; $j < sizeof($layer_list[$i]); $j++) {
                 if (!fwrite($fh, pack("N", $offset))) {
                     $this->error = "Could not write Tilepic offset table";
                     return false;
                 }
                 $offset += strlen($layer_list[$i][$j]);
             }
         }
         if ($this->debug) {
             print "offset table OK;";
         }
         if (!fwrite($fh, pack("N", $offset))) {
             $this->error = "Could not finish writing Tilepic offset table";
             return false;
         }
         # --- tiles
         for ($i = sizeof($layer_list) - 1; $i >= 0; $i--) {
             for ($j = 0; $j < sizeof($layer_list[$i]); $j++) {
                 if (!fwrite($fh, $layer_list[$i][$j])) {
                     $this->error = "Could not write Tilepic tile data";
                     return false;
                 }
             }
         }
         if ($this->debug) {
             print "tiles OK;";
         }
         unset($layer_list);
         # --- attributes
         if (!fwrite($fh, $attribute_list)) {
             $this->error = "Could not write Tilepic attributes";
             return false;
         }
         if ($this->debug) {
             print "attributes OK\n";
         }
         fclose($fh);
         return $pa_options;
     } else {
         $this->error = "Couldn't open output file {$ps_output_path}\n";
         return false;
     }
 }