= 0; $i-- ) MagickSetImagePixels( $wand, 0, $i, $w, 1, 'RGB', MW_CharPixel, $byteArray ); return $wand; } // render a PNG to a JPG with given quality and background function png2jpg( $blob, $quality=80, $background='#ffffff' ) { $png = NewMagickWand(); MagickReadImageBlob( $png, $blob ); $canvas = NewMagickWand(); MagickNewImage( $canvas, MagickGetImageWidth( $png ), MagickGetImageHeight( $png ), $background ); MagickCompositeImage( $canvas, $png, MW_SrcOverCompositeOp, 0, 0 ); MagickSetImageFormat( $canvas, 'JPEG' ); MagickSetImageCompressionQuality( $canvas, $quality ); return Image::getBlob( $canvas ); } // fix an image in the database static function fix( $id, $regen = false ) { $master = NewMagickWand(); $info = Database::getRow( "select format, master_w, master_h from images where iid=$id" ); if( $info['format'] == 'wmf' && $regen || ( $info['master_w'] < 315 && $info['master_h'] < 315 ) ) { // re-render WMF. write vector to disk first $vector = Database::getValue( 'select original_vector from images where iid=' . $id ); $fp = fopen( 'temp.wmf', 'w' ); fwrite( $fp, $vector ); fclose( $fp ); unlink( 'temp.png' ); Image::renderSizedWMF( 'temp.wmf', 'temp.png', 800, 800, true ); $master_blob = file_get_contents( 'temp.png' ); MagickReadImageBlob( $master, $master_blob ); $w = MagickGetImageWidth( $master ); $h = MagickGetImageHeight( $master ); $max = max( $w, $h ); if( $max < 700 ) { $factor = 800 / $max; Image::renderSizedWMF( 'temp.wmf', 'temp.png', $factor * 800, $factor * 800, true ); $master_blob = file_get_contents( 'temp.png' ); ClearMagickWand( $master ); MagickReadImageBlob( $master, $master_blob ); $w = MagickGetImageWidth( $master ); $h = MagickGetImageHeight( $master ); } Database::query( 'update images set master="' . addslashes( $master_blob ) . '", master_w=' . $w . ', master_h=' . $h . ' where iid=' . $id ); } else MagickReadImageBlob( $master, Database::getValue( 'select master from images where iid=' . $id ) ); // regenerate working and thumbnails $working = addslashes( Image::getBlob( Image::makeWorking( $master ) ) ); $thumbnail = addslashes( Image::getBlob( Image::makeThumbnail( $master ) ) ); // re-save Database::query( 'update images set working="' . $working . '", thumbnail="' . $thumbnail . '" where iid=' . $id ); } static function makeSemiMaster( $image ) { $master = MagickTransformImage( $image, NULL, '2048x2048' ); //MagickSetImageFormat( $thumbnail, "JPEG" ); // it should pick this up from the source? MagickSetImageCompressionQuality( $master, 90 ); return $master; } static function makeThumbnail( $image ) { $thumbnail = MagickTransformImage( $image, NULL, '100x100' ); //MagickSetImageFormat( $thumbnail, "JPEG" ); // it should pick this up from the source? MagickSetImageCompressionQuality( $thumbnail, 30 ); return $thumbnail; } static function makeWorking( $image ) { $working = MagickTransformImage( $image, NULL, '200x200' ); //MagickSetImageFormat( $working, "JPEG" ); MagickSetImageCompressionQuality( $working, 80 ); return $working; } // disk-based WMF conversion using external convert.exe utility // (gets far superior results that MagickWand API for some reason) static function renderWMF( $wmf_file, $output_file, $x_res, $y_res = false ) { //trigger_error( "renderWMF( WMF File: $wmf_file, OutputFile: $output_file, X: $x_res, Y: $y_res )" ); $use_external = true; if( !$y_res ) $y_res = $x_res; if( $use_external ) { // attempt conversion with external shell command $cmd = "convert -density {$x_res}x{$y_res} -background transparent $wmf_file $output_file"; //trigger_error( 'Executing shell command: "' . $cmd . '"' ); exec( $cmd ); } else { // attempt conversion with internal library functions $wand = NewMagickWand(); MagickReadImage( $wand, $wmf_file ); MagickSetImageResolution( $wand, $x_res, $y_res ); MagickSetImageFormat( $wand, 'PNG' ); MagickWriteImage( $wand, $output_file ); DestroyMagickWand( $wand ); } //exec( "convert -density {$x_res}x{$y_res} -transparent white $wmf_file $output_file" ); //exec( "convert -density {$x_res}x{$y_res} $wmf_file -draw 'matte 0,0 replace' $output_file" ); } // render to specific dimensions (ping image first and calculate required resolution) static function renderSizedWMF( $wmf_file, $output_file, $width, $height = false, $maintain_aspect = false ) { //trigger_error( "renderSizedWmf( WMF File: $wmf_file, Output File: $output_file, Width: $width, Height: $height )" ); $ping = NewMagickWand(); MagickPingImage( $ping, $wmf_file ); $w = MagickGetImageWidth( $ping ); $h = MagickGetImageHeight( $ping ); $res = MagickGetImageResolution( $ping ); $xr = $res[0]; $yr = $res[1]; //trigger_error( "renderSizedWmf: Width: $w, Height: $h, Res[xr]: $res[0], Res[yr]: $res[1]" ); // if maintain_aspect is specified, then width and height are really maximums, not absolutes if( $maintain_aspect && $width && $height ) { $aspect = $w / $h; if( $aspect > 1 ) $height = $width / $aspect; else $width = $height * $aspect; } if( $width ) $new_x = ( $width / $w ) * $xr; if( $height ) $new_y = ( $height / $h ) * $yr; if( !$new_x && !$new_y ) { $new_x = $xr; $new_y = $yr; } if( !$new_x ) $new_x = $new_y; if( !$new_y ) $new_y = $new_x; DestroyMagickWand( $ping ); Image::renderWMF( $wmf_file, $output_file, $new_x, $new_y ); } static function getSizedWMF( $wmf_file, $width, $height = false, $maintain_aspect = false ) { Image::renderSizedWMF( $wmf_file, 'temp.png', $width, $height, $maintain_aspect ); $image = NewMagickWand(); MagickReadImage( $image, 'temp.png' ); return $image; } // get WMF from database, copy to temp file, render to desired size, and return it static function getSizedWMF_DB( $wmf_id, $width, $height = false, $maintain_aspect = false ) { $wmf_blob = Database::getValue( 'select original_vector from image_store where iid=' . $wmf_id ); $wmf_file = Session::getDir() . 'temp.wmf'; $fp = fopen( $wmf_file, 'w' ); fwrite( $fp, $wmf_blob ); fclose( $fp ); return Image::getSizedWMF( $wmf_file, $width, $height, $maintain_aspect ); } // render to disk, then grab and return static function getRenderedWMF( $wmf_file, $res_x, $res_y = false ) { Image::renderWMF( $wmf_file, 'temp.png', $res_x, $res_y ); $image = NewMagickWand(); MagickReadImage( $image, 'temp.png' ); return $image; } // make an image from text, cropped (trimmed) to the right size static function makeTextImage( $string, $font, $size, $color ) { $image = NewMagickWand(); MagickNewImage( $image, strlen( $string ) * $size, $size * 2, '#ffffffff' ); // make new transparent canvas, large enough for the text $text = NewDrawingWand(); DrawSetFontSize( $text, $size ); DrawSetFillColor( $text, $color ); DrawSetGravity( $text, MW_CenterGravity ); // put the text dead center DrawSetFont( $text, Font::getPath( $font ) ); DrawAnnotation( $text, 0, 0, $string ); // draw the text MagickDrawImage( $image, $text ); // render the text to the canvas MagickTrimImage( $image ); // trim canvas (this will crop it to just the text dimensions) DestroyDrawingWand( $text ); return $image; } // call makeTextImage(), and then write it to a temp file in the user's session dir, return filename static function makeTextImageFile( $string, $font, $size, $color ) { require_once( 'includes/Session.class.php' ); $image = Image::makeTextImage( $string, $font, $size, $color ); // record dimensions in session $_SESSION['new_text_width'] = MagickGetImageWidth( $image ); $_SESSION['new_text_height'] = MagickGetImageHeight( $image ); $filename = md5( $color . '|' . $font . '|' . $size . '|' . $string ) . '.png'; $path = Session::getDir() . $filename; MagickSetImageFormat( $image, 'PNG' ); MagickWriteImage( $image, $path ); DestroyMagickWand( $image ); return $filename; } static function estimateFontSize( $string, $font, $width, $height ) { $image = NewMagickWand(); $text = NewDrawingWand(); MagickNewImage( $image, 1, 1 ); // make new dummy canvas, required for FontMetrics // determine metrics for 100 point, then use this to calculate required font size for specified dimensions DrawSetFontSize( $text, 100 ); DrawSetFont( $text, Font::getPath( $font ) ); $metrics = MagickQueryFontMetrics( $image, $text, $string ); $w_size = $width / $metrics[4] * 100; $h_size = $height / $metrics[5] * 100 * 1.3; DestroyMagickWand( $image ); DestroyDrawingWand( $text ); return max( $w_size, $h_size ); } // make a text image at least as big as specified dimensions static function makeSizedTextImage( $string, $font, $color, $width, $height ) { $size = Image::estimateFontSize( $string, $font, $width, $height ); return Image::makeTextImage( $string, $font, $size, $color ); } static function makeSizedTextImageFile( $string, $font, $color, $width, $height ) { $size = Image::estimateFontSize( $string, $font, $width, $height ); return Image::makeTextImageFile( $string, $font, $size, $color ); } } // end class ?>