Пример #1
0
 /**
  * Generates a portion of an ImageMagick convert command to apply an alpha mask
  *
  * Note: More accurate values for radii used to generate the LASCO C2 & C3 alpha masks:
  *  rocc_outer = 7.7;   // (.9625 * orig)
  *  rocc_inner = 2.415; // (1.05 * orig)
  *
  *  LASCO C2 Image Scale
  *      $lascoC2Scale = 11.9;
  *
  *  Solar radius in arcseconds, source: Djafer, Thuillier and Sofia (2008)
  *      $rsunArcSeconds = 959.705;
  *      $rsun           = $rsunArcSeconds / $lascoC2Scale;
  *                      = 80.647 // Previously, used hard-coded value of 80.814221
  *
  *  Generating the alpha masks:
  *      $rocc_inner = 2.415;
  *      $rocc_outer = 7.7;
  *
  *      // convert to pixels
  *      $radius_inner = $rocc_inner * $rsun;
  *      $radius_outer = $rocc_outer * $rsun;
  *      $innerCircleY = $crpix2 + $radius_inner;
  *      $outerCircleY = $crpix2 + $radius_outer;
  *
  *      exec("convert -size 1024x1024 xc:black -fill white -draw \"circle $crpix1,$crpix2 $crpix1,$outerCircleY\"
  *          -fill black -draw \"circle $crpix1,$crpix2 $crpix1,$innerCircleY\" +antialias LASCO_C2_Mask.png")
  *
  *  Masks have been pregenerated and stored in order to improve performance.
  *
  *  Note on offsets:
  *
  *   The original CRPIX1 and CRPIX2 values used to determine the location of the center of the sun in the image
  *   are specified with respect to a bottom-left corner origin. The values passed in to this method from the tile
  *   request, however, specify the offset with respect to a top-left corner origin. This simply makes things
  *   a bit easier since ImageMagick also treats images as having a top-left corner origin.
  *
  *  Region of interest:
  *
  *    The region of interest (ROI) below is specified at the original JP2 image scale.
  *
  * @param object $imagickImage an initialized Imagick object
  *
  * @return void
  */
 protected function setAlphaChannel(&$imagickImage)
 {
     $maskWidth = 1040;
     $maskHeight = 1040;
     $mask = HV_ROOT_DIR . '/resources/images/alpha-masks/LASCO_' . $this->uiLabels[2]['name'] . '_Mask.png';
     if ($this->reduce > 0) {
         $maskScaleFactor = 1 / pow(2, $this->reduce);
     } else {
         $maskScaleFactor = 1;
     }
     $maskTopLeftX = ($this->imageSubRegion['left'] + ($maskWidth - $this->jp2->getWidth()) / 2 - $this->offsetX) * $maskScaleFactor;
     $maskTopLeftY = ($this->imageSubRegion['top'] + ($maskHeight - $this->jp2->getHeight()) / 2 - $this->offsetY) * $maskScaleFactor;
     $width = $this->subfieldWidth * $maskScaleFactor;
     $height = $this->subfieldHeight * $maskScaleFactor;
     // $maskTopLeft coordinates cannot be negative when cropping, so if they are, adjust the width and height
     // by the negative offset and crop with zero offsets. Then put the image on the properly-sized image
     // and offset it correctly.
     $cropWidth = round($width + min($maskTopLeftX, 0));
     $cropHeight = round($height + min($maskTopLeftY, 0));
     $mask = new IMagick($mask);
     // Imagick floors pixel values but they need to be rounded up or down.
     // Rounding cannot be done in the previous lines of code because some addition needs to take place first.
     $maskTopLeftX = round($maskTopLeftX);
     $maskTopLeftY = round($maskTopLeftY);
     $width = round($width);
     $height = round($height);
     $mask->scaleImage($maskWidth * $maskScaleFactor, $maskHeight * $maskScaleFactor);
     $mask->cropImage($cropWidth, $cropHeight, max($maskTopLeftX, 0), max($maskTopLeftY, 0));
     $mask->resetImagePage($width . 'x' . $height . '+0+0');
     $mask->setImageBackgroundColor('black');
     $mask->extentImage($width, $height, $width - $cropWidth, $height - $cropHeight);
     $imagickImage->setImageExtent($width, $height);
     $imagickImage->compositeImage($mask, IMagick::COMPOSITE_COPYOPACITY, 0, 0);
     if ($this->options['opacity'] < 100) {
         $mask->negateImage(true);
         $imagickImage->setImageClipMask($mask);
         $imagickImage->setImageOpacity($this->options['opacity'] / 100);
     }
     $mask->destroy();
 }