PHP - imagick: close open areas in image - php

After the follow code:
$im = new \Imagick('fu.png');
$im->thresholdimage(0.9, 127);
I'm getting this image:
so I need to close the open areas.
When I copy the code from http://phpimagick.com/Imagick/morphology?morphologyType=9 which is:
$im = new \Imagick('fu.png');
$im->thresholdimage(0.9, 127);
$canvas = $this->getCharacterOutline();
$kernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_DISK, "6");
$canvas->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $kernel);
header("Content-Type: image/png");
echo $im->getImageBlob();
I'm getting error: PHP Fatal error: Using $this when not in object context in..
I don't have ANY idea how to use this, I've never seen anything like it and I'm sure it's not a matter of logical thinking but knowing exactly how the hell to do that or you're f***ed.
Please help!
UPDATE:
As Roljhon explained I need to use the getchar.. function so I did:
private function getCharacterOutline()
{
$im = new \Imagick('fu.png');
$im->thresholdimage(0.9, 127);
$character = new \Imagick();
$character->newPseudoImage(
$im->getImageWidth(),
$im->getImageHeight(),
"canvas:white"
);
$canvas = new \Imagick();
$canvas->newPseudoImage(
$im->getImageWidth(),
$im->getImageHeight(),
"canvas:black"
);
$character->compositeimage(
$im,
\Imagick::COMPOSITE_COPYOPACITY,
0, 0
);
$canvas->compositeimage(
$character,
\Imagick::COMPOSITE_ATOP,
0, 0
);
$canvas->setFormat('png');
return $canvas;
}
$canvas = $this->getCharacterOutline();
$kernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_DISK, "6");
$canvas->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $kernel);
header("Content-Type: image/png");
echo $im->getImageBlob();
I don't know what I'm doing and what this piece of crap supposed to do anyway... I'm getting error ofc...

Do it like this instead since getCharacterOutline is a standalone function and not within a class
UPDATED
$canvas = getCharacterOutline();
$kernel = \ImagickKernel::fromBuiltIn(\Imagick::KERNEL_DISK, "6");
$canvas->morphology(\Imagick::MORPHOLOGY_CLOSE, 1, $kernel);
header("Content-Type: image/png");
echo $canvas->getImageBlob();

Related

Display CMYK black using Imagick

I am having the issue when converting to pdf the draw layer font colour is no longer black. I have tried adding this $image->quantizeImage(255, \Imagick::COLORSPACE_CMYK , 0, TRUE, FALSE); however, the quality is effected.
$draw = new ImagickDraw();
$canvas = new Imagick();
$draw->setFillColor("#000000");
$canvas->annotateImage($draw, $x, $y, 0,"Firstname");
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
$image->setImageFormat('pdf');
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="preview.pdf"');
echo $image->getImagesBlob();
update 1
I'm just trying to do some tests to see why the colour is incorrect. The Imagick colours appear to be inverted. For example, this code produces
$im->newImage($imageDimensions['width'], $imageDimensions['height'], new ImagickPixel('white'));
Update 2
I have discovered that the font colour becomes inverted. I do have a custom method that does inverse this. but causes the font to be off. Why does the font colour change to white. To test switch between the commented out $img
$image = new imagick();
$img = file_get_contents("https://i.pinimg.com/originals/7c/cb/01/7ccb010d8fddc4bcd84587ef3c34d100.jpg", false);
//$img = file_get_contents("https://www.footballcomics.co.uk/wp-content/uploads/2020/09/comic_1_page_3_bottom.jpg", false);
$image->readImageBlob($img);
$draw = new ImagickDraw();
$canvas = new Imagick();
$canvas->newPseudoImage(
600,
600,
"canvas:none"
);
$draw->setFillColor("#000000");
$draw->setFontSize( 26);
//$draw->setFont(plugin_dir_path( __FILE__ ) . './assets/fonts/aAntiCorona.ttf');
$canvas->annotateImage($draw, 300, 300, 0,"Firstname");
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
$image->setImageFormat('pdf');
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="preview.pdf"');
echo $image->getImagesBlob();
Update 3
I have tried adding profiles to the Imagick, believe I'm on the right track here. But still not presenting correctly
$icc_cmyk = file_get_contents(plugin_dir_path( '/JapanColor2001Coated.icc');
$canvas->profileImage('icc', $icc_cmyk);
Update 4
Running the code below will allow you to see Firstname be a different shade. Need that to match the other black text from the image.
$image = new imagick();
//$img = file_get_contents("https://i.pinimg.com/originals/7c/cb/01/7ccb010d8fddc4bcd84587ef3c34d100.jpg", false);
$img = file_get_contents("https://www.footballcomics.co.uk/wp-content/uploads/2020/09/comic_1_page_3_top.tif", false);
$image->readImageBlob($img);
$image->setImageColorspace(Imagick::COLORSPACE_CMYK);
$imageDimensions = $image->getImageGeometry();
$draw = new ImagickDraw();
//$draw->setImageColorspace(Imagick::COLORSPACE_CMYK);
$canvas = new Imagick();
$canvas->newPseudoImage(
$imageDimensions['width'],
$imageDimensions['height'],
"canvas:none"
);
$canvas->setImageColorspace(Imagick::COLORSPACE_CMYK);
$fillColor = new \ImagickPixel();
$fillColor->setColor('cmyk(0%,0%,0%,100%');
$draw->setFillColor($fillColor);
$draw->setFontSize( 26);
//$draw->setFont(plugin_dir_path( __FILE__ ) . './assets/fonts/aAntiCorona.ttf');
$canvas->annotateImage($draw, 45, 89, 0,"Firstname");
$canvas->transformImageColorspace(Imagick::COLORSPACE_CMYK);
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
$image->setImageFormat('pdf');
header('Content-type: application/pdf');
header('Content-Disposition: inline; filename="preview.pdf"');
echo $image->getImagesBlob();
You don't need, and shouldn't set the canvas image to CMYK before compositing it.
I actually don't know what is happening under the hood, but I think what is happening is that attempting to convert an RGB image that contains transparency to CMYK is a silly thing to do, and so instead of 'converting' it, ImageMagick assumes you just want to treat that canvas image as CMYK already, and so the colours get mapped (but not transformed) from RGBA to CMYK.
However, ImageMagick is understands that compositing images that contain transparency onto a CMYK image is a sensible thing to do, and so it supports composting RGBA images onto CMYK and doing the appropriate conversion at the same time.
Anyway, regardless of what is actually happening internally, this code appears to work:
<?php
$image = new Imagick();
$img = file_get_contents("second.tif", false);
$image->readImageBlob($img);
$imageDimensions = $image->getImageGeometry();
$draw = new ImagickDraw();
$canvas = new Imagick();
$canvas->newPseudoImage(
$imageDimensions['width'],
$imageDimensions['height'],
"canvas:none"
);
$fillColor = new \ImagickPixel();
$fillColor->setColor('black');
$draw->setFillColor($fillColor);
$draw->setFontSize( 26);
$canvas->annotateImage($draw, 45, 89, 0,"Firstname");
$canvas->transformImageColorspace(Imagick::COLORSPACE_CMYK);
$image->compositeImage($canvas,Imagick::COMPOSITE_ATOP,0, 0);
$image->setImageFormat('pdf');
$image->writeImages(__DIR__ . "working.pdf", false);

PHP Imagick black areas after converting PDF to JPG

I'm using Imagick to generate JPG thumbnails for PDFs files but some of them generate with black areas (http://i.imgur.com/fKBncKw.jpg) – I'm assuming it's caused by transparency in the PDFs but can anything be done about it?
Code I'm using to generate these:
$imagick = new Imagick($filename);
$imagick->setIteratorIndex(0);
$imagick->setImageFormat('jpg');
return $imagick->getImageBlob();
Is there a way to flatten the PDF and/or add a white background so that the black areas don't appear?
Here is a solution which will only work for PNG to JPG.
This code adds a white background to the transparent areas in PNG and converts it to JPG.
What it does?
This code takes all PNG images from a folder, converts them to JPG's with white backgrounds and saves them in another folder.
<?php
ini_set('max_execution_time', 3000);
$dir = 'transparent/';
$arr = scandir($dir);
for($i=0;$i<count($arr);$i++)
{
if($i==0 || $i==1)
{
}
else{
$input_file = "transparent/".$arr[$i];
$output_file = "White/".str_replace('.png','.jpg',$arr[$i]);
$input = imagecreatefrompng($input_file);
list($width, $height) = getimagesize($input_file);
$output = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($output, 255, 255, 255);
imagefilledrectangle($output, 0, 0, $width, $height, $white);
imagecopy($output, $input, 0, 0, 0, 0, $width, $height);
imagejpeg($output, $output_file);
}
}
?>
Its Image Processing and GD in PHP.
PHP Manual
Hope it helps, you can change it as you want.
Try this code: Imagick::setCompressionQuality
$im = new imagick(realpath($file).'[0]');
$im->setCompression(Imagick::COMPRESSION_JPEG);
$im->setCompressionQuality(100);
$im->setImageFormat("jpeg");
$im->writeImage("imagename.jpg");
Alternative solution: this may help:
<?php
//Note that the function returns an Imagick object and does not modify the existing object. Below is my code for converting a PNG with transparency into a JPG with a background color. This code illustrates the difference.
$im = new Imagick($filename);
$im->setImageBackgroundColor('white');
$im->flattenImages(); // This does not do anything.
$im = $im->flattenImages(); // Use this instead.
$im->setImageFormat('jpg');
$im->writeImage('image.jpg');
?>
use like this
class ImageConvertorLib{
private $CI;
/**
* loading codeIgniter instance
*/
public function __construct(){
$this->CI =& get_instance();
}
public function pdfToJpg($param){
$filename = $param['filename'];
$image_name = $param['image_name'];
$path = $param['path'];
$db_path = $param['db_path'];
$im = new Imagick();
$im->setResolution(220,220);
$im->readimage($filename."[0]");
$im->setImageFormat('jpeg');
$im->setImageBackgroundColor('#ffffff');
$im->flattenImages();
$image_name = $image_name.".jpg";//"save_as_name.jpg";
$imageprops = $im->getImageGeometry();
/*if ($imageprops['width'] <= 175 && $imageprops['height'] <= 300) {
// don't upscale
} else {
$im->resizeImage(175,300, imagick::FILTER_LANCZOS, 0.9, true);
}*/
$im->writeImage($path.$image_name);
if($im){
$Img = array();
$Img['status'] = 1;
$Img['image'] = ($db_path.$image_name);
return $Img;
}
$im->clear();
$im->destroy();
}
}
After endless attempts to append a pdf file with a jpeg image without getting black areas, I found the solution: the function transformImageColorspace
Used in this order works perfectly:
$im = new Imagick();
$im->readImage("file.pdf");
$im->transformImageColorspace(Imagick::COLORSPACE_SRGB);
$im->setImageFormat('jpeg');
$im->writeImage('image.jpg');

Draw circle with php imagemagick

I just want to get the basic idea of how to draw a circle with php5 imagemagick.
I have looked at the page, http://php.net/manual/en/imagickdraw.circle.php
but the example there is too confusing. I want to just draw a circle then mess around with that. Can someone give me a simple php5 imagemagick circle example?
I have tried:
<?php
header("Content-type: image/jpeg");
$circle = new ImagickDraw();
$draw->circle (10, 10, 60, 10);
//echo $circle;
?>
any numerous variants, but I cant get a circle drawn.
I hope this is what you're looking for:
<?php
$draw = new ImagickDraw ();
//given that $x and $y are the coordinates of the centre, and $r the radius:
$draw->circle ($x, $y, $x + $r, $y);
?>
Danak on the php chat page provided me with this link, Which provides an active example.
http://www.phpimagick.com/ImagickDraw/circle
The variable names are concise and descriptive,
and the example makes it easy for me to understand what is going on.
function circle($strokeColor, $fillColor, $backgroundColor, $originX, $originY, $endX, $endY) {
//Create a ImagickDraw object to draw into.
$draw = new \ImagickDraw();
$strokeColor = new \ImagickPixel($strokeColor);
$fillColor = new \ImagickPixel($fillColor);
$draw->setStrokeOpacity(1);
$draw->setStrokeColor($strokeColor);
$draw->setFillColor($fillColor);
$draw->setStrokeWidth(2);
$draw->setFontSize(72);
$draw->circle($originX, $originY, $endX, $endY);
$imagick = new \Imagick();
$imagick->newImage(500, 500, $backgroundColor);
$imagick->setImageFormat("png");
$imagick->drawImage($draw);
header("Content-Type: image/png");
echo $imagick->getImageBlob();
}

PHP GD Library cannot Merge to image using function

This is my php class to merge to images
mergepic.php
class mergepic{
public function merge_barchart_drawing($object,$obj)
{
$src = imagecreatefrompng($obj->barchart());
$dest = imagecreatefrompng($object->drawing());
//$src = imagecreatefrompng('http://localhost/graph/barchart.php?barchart='.$_GET['barchart'].'&max='.$_GET['max'].'&digit='.$_GET['digit']);
//$dest = imagecreatefrompng('http://localhost/graph/drawing.php?drawings='.$_GET['drawings'].'&max='.$_GET['max'].'&digit='.$_GET['digit']);
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagecopymerge($dest, $src, 10, 9, 0, 9, 700, 500, 100); //have to play with these numbers for it to work for you, etc.
header('Content-Type: image/png');
imagepng($dest);
imagedestroy($dest);
imagedestroy($src);
}
}
creating_obj,php
<?
include('drawing.php');
include('barchart.php');
include('mergepic_class.php');
$draw = new drawgraph();
$barchart = new barchart_graph();
$merge_draw = new mergepic();
$merge_draw_bar = $merge_draw->merge_barchart_drawing($draw,$barchart);
?>
If i run createing_obj.php i am geting only one image file its not mergeing two images. Instead of class if i use url inside imagecreatefrompng() it working fine.
Any idea please ?
function barchart(){
return $canvas;
}
OR (If you want to save this layer image to disk):
function barchart(){
$path = {path where to save file};
$filename = {filename to save and extension};
imagepng($canvas,$path.$filename);
return $path.$filename;
}
Do this same for the other(drawing) class too..

Call to undefined method Imagick::writeImageFile()

I've a problem with Imagick - PHP.
I've this code :
function createImages ($src, $dst, $width, $height)
{
$image = new Imagick($src);
$image->stripImage();
$color = new ImagickPixel();
$color->setColor('rgb(255,255,255)');
if(resizeimage($image, $width, $height)) {
$image->borderimage($color,
intval(($width - $image->getimagewidth()) / 2),
intval(($height - $image->getimageheight()) / 2));
$image1 = new Imagick();
$image1->newImage($width, $height, new ImagickPixel('white'));
$image1->setImageColorspace($image->getImageColorspace());
$image1->compositeImage($image, $image1->getImageCompose(), 0, 0);
$image1->setImageCompressionQuality(90);
$image1->setimagecompression(Imagick::COMPRESSION_JPEG);
$image1->setformat('jpeg');
$fileHandle = fopen($dst, "w");
$image1->writeImageFile($fileHandle);
$color->destroy();
$image1->destroy();
}
$image->destroy();
return true;
}
And this error :
Fatal error: Call to undefined method Imagick::writeImageFile()
I don't understand why all other methods work good, but not writeImageFile(). Can you help me please?
The writeImageFile function is available in ImageMagick version 6.3.6, so perhaps your version is not recent enough? There is also writeImage which may be a usable alternative in your case: http://www.php.net/manual/en/imagick.writeimage.php

Categories