protected function create_images($text, $hash) { // Check parameters. if (trim($text) === '') { return array(); } if (!mb_check_encoding($text, 'UTF-8')) { throw new IMGTextException('String is not valid UTF-8'); } $font_filename = $this->font_dir . '/' . $this->font_name . '.' . $this->font_ext; if (!file_exists($font_filename)) { throw new IMGTextException('Font not found: ' . $font); } $font_size = (int) $this->font_size; if ($font_size <= 0) { throw new IMGTextException('Invalid font size: ' . $size); } if (!preg_match('/^#?(?:[0-9a-f]{3})(?:[0-9a-f]{3})?$/', $this->color)) { throw new IMGTextException('Invalid text color: ' . $this->color); } if ($this->background_color !== false && !preg_match('/^#?(?:[0-9a-f]{3})(?:[0-9a-f]{3})?$/', $this->background_color)) { throw new IMGTextException('Invalid background color: ' . $this->background_color); } if (!is_array($this->padding) || count($this->padding) != 4) { throw new IMGTextException('Invalid padding. Please use array with 4 members.'); } if (!is_array($this->shadow_offset) || count($this->shadow_offset) != 2) { throw new IMGTextException('Invalid shadow offset. Please use array with 2 members.'); } if ($this->shadow_opacity < 0 || $this->shadow_opacity > 127) { throw new IMGTextException('Invalid shadow opacity. Please use a value between 0 (opaque) and 127 (transparent).'); } // Split the text into words. $words = preg_split('/\\s+/u', $text); // Parse the padding amount. $padding_top = intval($this->padding[0]); $padding_right = intval($this->padding[1]); $padding_bottom = intval($this->padding[2]); $padding_left = intval($this->padding[3]); // Get size information for each word. We do this first, in order to find out the maximum height. $fragments = array(); $max_height = 0; $max_top = 0; foreach ($words as $w) { $w = trim($w); if ($w === '') { continue; } // Get the bounding box size. $bounds = imageTTFBBox($font_size, 0, $font_filename, $w); // Get more useful information from GD's return values. $width = $bounds[2] - $bounds[0]; $height = $bounds[3] - $bounds[5]; $left = -$bounds[6] - 1; $top = -$bounds[7] - 1; // Update the max height/top values if necessary. if ($height > $max_height) { $max_height = $height; } if ($top > $max_top) { $max_top = $top; } $fragments[] = array($w, $width, $height, $left, $top); } // Create images for each word. $count = 1; $return = array(); foreach ($fragments as $f) { list($w, $width, $height, $left, $top) = $f; $img_width = $width + $padding_left + $padding_right; $img_height = $this->image_height ? $this->image_height : $max_height + $padding_top + $padding_bottom; $text_left = $left + $padding_left; $text_top = $max_top + $padding_top; // Adjust image size and text location if there's a shadow. if ($this->shadow) { if ($this->shadow_offset[0] < 0) { $shadow_space_left = $this->shadow_blur - $this->shadow_offset[0]; $shadow_space_right = max(0, $this->shadow_blur + abs($this->shadow_offset[0])); $shadow_left = $text_left + $shadow_space_left; $text_left = $text_left + $shadow_space_left - $this->shadow_offset[0]; } else { $shadow_space_left = max(0, $this->shadow_blur - $this->shadow_offset[0]); $shadow_space_right = $this->shadow_blur + $this->shadow_offset[0]; $shadow_left = $text_left + $shadow_space_left + $this->shadow_offset[0]; $text_left = $text_left + $shadow_space_left; } if ($this->shadow_offset[1] < 0) { $shadow_space_top = $this->shadow_blur - $this->shadow_offset[1]; $shadow_space_bottom = max(0, $this->shadow_blur + abs($this->shadow_offset[1])); $shadow_top = $text_top + $shadow_space_top; $text_top = $text_top + $shadow_space_top - $this->shadow_offset[1]; } else { $shadow_space_top = max(0, $this->shadow_blur - $this->shadow_offset[1]); $shadow_space_bottom = $this->shadow_blur + $this->shadow_offset[1]; $shadow_top = $text_top + $shadow_space_top + $this->shadow_offset[1]; $text_top = $text_top + $shadow_space_top; } $img_width += $shadow_space_left + $shadow_space_right; $img_height += $shadow_space_top + $shadow_space_bottom; } // Initialize the image and draw the background. $img = imageCreateTrueColor($img_width, $img_height); if ($this->background_color === false) { imageSaveAlpha($img, true); imageAlphaBlending($img, false); $img_background_color = imageColorAllocateAlpha($img, 255, 255, 255, 127); imageFilledRectangle($img, 0, 0, $img_width, $img_height, $img_background_color); imageAlphaBlending($img, true); } else { $img_background_colors = $this->hex2rgb($this->background_color); $img_background_color = imageColorAllocate($img, $img_background_colors[0], $img_background_colors[1], $img_background_colors[2]); imageFilledRectangle($img, 0, 0, $img_width, $img_height, $img_background_color); } // Draw the shadow. if ($this->shadow) { // Blurred shadow on a transparent background needs special treatment because of GD's limitations. if ($this->shadow_blur && $this->background_color === false) { // Create a temporary image for the shadow. $temp = imageCreateTrueColor($img_width, $img_height); imageSaveAlpha($temp, true); imageFilledRectangle($temp, 0, 0, $img_width, $img_height, imageColorAllocate($temp, 127, 127, 127)); // Draw the shadow text on the temporary image, and blur it. $temp_text_color = imageColorAllocate($temp, $this->shadow_opacity, $this->shadow_opacity, $this->shadow_opacity); imageTTFText($temp, $font_size, 0, $shadow_left, $shadow_top, $temp_text_color, $font_filename, $w); for ($i = 0; $i < $this->shadow_blur; $i++) { imageFilter($temp, IMG_FILTER_GAUSSIAN_BLUR); } // Use the blurred shadow as an alpha mask on the original image. $shadow_colors = $this->hex2rgb($this->shadow_color); for ($x = 0; $x < $img_width; $x++) { for ($y = 0; $y < $img_height; $y++) { $alpha = imageColorAt($temp, $x, $y) & 0xff; imageSetPixel($img, $x, $y, imageColorAllocateAlpha($img, $shadow_colors[0], $shadow_colors[1], $shadow_colors[2], $alpha)); } } imageDestroy($temp); } else { $shadow_colors = $this->hex2rgb($this->shadow_color); $shadow_color = imageColorAllocateAlpha($img, $shadow_colors[0], $shadow_colors[1], $shadow_colors[2], $this->shadow_opacity); imageTTFText($img, $font_size, 0, $shadow_left, $shadow_top, $shadow_color, $font_filename, $w); for ($i = 0; $i < $this->shadow_blur; $i++) { imageFilter($img, IMG_FILTER_GAUSSIAN_BLUR); } } } // Draw the word. $text_colors = $this->hex2rgb($this->color); $text_color = imageColorAllocate($img, $text_colors[0], $text_colors[1], $text_colors[2]); imageTTFText($img, $font_size, 0, $text_left, $text_top, $text_color, $font_filename, $w); // Save to a PNG file. $filename = '/imgtext.' . $hash . '.word-' . str_pad($count, 3, '0', STR_PAD_LEFT) . '.png'; imagePNG($img, $this->cache_local_dir . $filename); imageDestroy($img); // Add information about this word to the return array. $return[] = array('word' => $w, 'path' => $this->cache_url_prefix . $filename); $count++; } // Returns a list of dictionaries, each containing a word and the corresponding image URL. return $return; }
/** * @param $resource * @param $color * @return bool */ public function set_part_color(&$resource, $color) { $replace_color = $this->HEX2RGB($color); if (LITE_RECOLOR_FUNCTION) { imageFilter($resource, IMG_FILTER_COLORIZE, $replace_color[0] - 255, $replace_color[1] - 255, $replace_color[2] - 255); } else { $width = imageSX($resource); $height = imageSY($resource); for ($y = 0; $y < $height; $y++) { for ($x = 0; $x < $width; $x++) { $rgb = imageColorsForIndex($resource, imageColorAt($resource, $x, $y)); $nr = max(round($rgb['red'] * $replace_color[0] / 255), 0); $ng = max(round($rgb['green'] * $replace_color[1] / 255), 0); $nb = max(round($rgb['blue'] * $replace_color[2] / 255), 0); imageSetPixel($resource, $x, $y, imageColorAllocateAlpha($resource, $nr, $ng, $nb, $rgb['alpha'])); } } } return true; }