Divide photo to X and Y pieces - php

I have a 96x96 image and i need to divide it in 36 pieces of 16x16 and i have a script given below works fine on my localhost but not working on my webhost.
function makeTiles($name, $imageFileName, $crop_width, $crop_height)
{
$dir = "/pic";
$slicesDir = "/pic/16X16";
// might be good to check if $slicesDir exists etc if not create it.
$ImgExt = split(".",$imageFileName);
$inputFile = $dir . $imageFileName;
$img = new Imagick($inputFile);
$imgHeight = $img->getImageHeight();
$imgWidth = $img->getImageWidth();
$cropWidthTimes = ceil($imgWidth/$crop_width);
$cropHeightTimes = ceil($imgHeight/$crop_height);
for($i = 0; $i < $cropWidthTimes; $i++)
{
for($j = 0; $j < $cropHeightTimes; $j++)
{
$img = new Imagick($inputFile);
$x = ($i * $crop_width);
$y = ($j * $crop_height);
$img->cropImage($crop_width, $crop_height, $x, $y);
$data = $img->getImageBlob();
$newFileName = $slicesDir . $name . "_" . $x . "_" . $y . ".".$ImgExt[1];
$result = file_put_contents ($newFileName, $data);
}
}
}
Getting fatal error
Fatal error: Class 'Imagick' not found in myfile.php line number
My host saying:
Imagick and image magic both are same unfortunately, we do not have
them as a PHP module we have binaries like ImageMagick binary and
Image magic path is /usr/local/bin. Include this function in your
script and check the website functionality from your end.
I dont know how to fix this error.

If I understand it correctly you will have to invoke the imagick binary from your script using exec():
exec('/usr/local/bin/convert '.$inputFile.' -crop 96x96+ox+oy '.$newFilename);
The ox and oy should be replaced with the correct offset values.
Here is are a couple of links that might help:
How do I use Imagick binaries from php
Imagick - Convert Command-line tool

Related

Convert ICO to PNG using PHP Imagick

I am currently trying to convert an ICO file to a 16x16 px PNG, using PHP-Imagick. What I've tried so far:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$im->writeImages($targetFile, true);
This works partially. The problem is, that an ICO file may contain multiple images, so the code above creates multiple PNG files
favicon-0.png
favicon-1.png
...
for every size. This is okay, but then, I need the possibility to find the one that is close to 16x16 px, scale it down (if needed) and delete all others. For this, I already tried some things and this is where I'm stuck currently:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
if ($count > 1) {
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$tmpImageWidth = $im->getImageWidth();
$tmpImageHeight = $im->getImageHeight();
// ???
}
}
$im->writeImages($targetFile, true);
I guess, i would find a working way with some trial and error. But I would like to know, if there's an easier way to achieve this.
TL;DR: I need a simple way to convert an ICO file of any size to a 16x16 px PNG, using PHP-Imagick (using GD isn't an option).
Update:
My (currently working but maybe suboptimal) solution:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);
Updated Answer
On re-reading your question, it seems you actually want to make a PNG file from an ICO file. I have read the Wikipedia entry for ICO files and, as usual, it is a poorly specified complicated mess of closed source Microsoft stuff. I can't tell if they come in some order.. smallest first, or largest first, so I think my recommendation would be to simply iterate through all the images in your ICO file, as you planned, and get the one with the largest number of pixels and resize that to 16x16.
Original Answer
Too much for a comment, maybe not enough for an answer... I don't use PHP Imagick much at alll, but if you use ImageMagick at the command-line in the Terminal, you can set the ICO sizes like this:
magick INPUT -define icon:auto-resize="256,128,96,64,16" output.ico
to say what resolutions you want embedded in the output file. As I said, I don't use PHP, but I believe the equivalent is something like:
$imagick->setOption('icon:auto-resize', "16");
Sorry I can't help better, I am just not set up to use PHP and Imagick, but hopefully you can work it out from here.
My final solution:
<?php
if (empty(\Imagick::queryFormats("ICO"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/favicon.ico';
$targetFile = __DIR__ . '/favicon.png';
$im = new \Imagick($sourceFile);
$count = $im->getNumberImages();
$targetWidth = $targetHeight = 16;
if ($count > 1) {
$images = [];
for ($x = 1; $x <= $count; $x++) {
$im->previousImage();
$images[] = [
'object' => $im,
'size' => $im->getImageWidth() + $im->getImageHeight()
];
}
$minSize = min(array_column($images, 'size'));
$image = array_values(array_filter($images, function($image) use ($minSize) {
return $minSize === $image['size'];
}))[0];
$im = $image['object'];
if ($image['size'] <> $targetWidth + $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
else {
if ($im->getImageWidth() <> $targetWidth || $im->getImageHeight() <> $targetHeight) {
$im->cropThumbnailImage($targetWidth, $targetHeight);
}
}
$im->writeImage($targetFile);

Unable to get the dimensions of uploaded file in php

Need to get the dimensions of the uploaded files such as width, height, size, etc. I tried using getimagesize() , but that does not works. I get an error,
Warning: getimagesize(C:/wamp/www/KSHRC/uploads/): failed to open stream: No such file or directory in C:\wamp\www\KSHRC\registration\multi_fileupload.php on line 31
and
Notice: Array to string conversion in C:\wamp\www\KSHRC\registration\multi_fileupload.php on line 31
Here's the code,
for($i=0; $i < count($_FILES['userfile']['tmp_name']);$i++)
{
$root = $_SERVER['DOCUMENT_ROOT']."/KSHRC/uploads/";
$filename = $_FILES['userfile']['name'][$i];
echo $size = getimagesize($root.$filename);
}
Please help me..
you have to move the file from tmp to your desired folder first then you can get the image size by using your function getimagesize
for($i=0; $i < count($_FILES['userfile']['tmp_name']);$i++)
{
$root = $_SERVER['DOCUMENT_ROOT']."/KSHRC/uploads/";
$filename = $_FILES['userfile']['name'][$i];
move_uploaded_file($_FILES['userfile']['tmp_name'], $root.$filename);
echo $size = getimagesize($root.$filename);
}
Update
you can also get the file size by $_FILES['userfile']['size'] Like this
$size = $_FILES['userfile']['size'];
this will return size in bytes
UPDATE 2
$ARR_FILES = $_FILES['userfile'];
for($i=0; $i < count($ARR_FILES);$i++)
{
$root = $_SERVER['DOCUMENT_ROOT']."/KSHRC/uploads/";
$filename = $ARR_FILES[$i]['name'];
$tmp_name = $ARR_FILES[$i]['tmp_name'];
list($width, $height, $type, $attr) = getimagesize($tmp_name);
echo $width;
echo $height;
}

writeImage with imagick in codeigniter

I'm using codeigniter and imagick for convert pdf to png image file.
$im = new imagick();
$im->setResolution ( 110,110);
$im->readImage($target_path);
$num_page = $im->getnumberimages();
for ($i=0; $i < $num_page ; $i++) {
$im->readImage($target_path."[".$i."]");
$im->setImageFormat('png');
$im->writeImage(?);
}
$im->destroy();
I don't know how save this file in codeignietr_folder/assets/pdf-img
I tried ../../assets/test.png and localhost/codeignietr_folder/assets/pdf-img
but it doesn't work!
how could i do it?
You can use $im->writeImage($file); where
$file = getcwd() . '/assets/pdf-img/test.png';

Read text in image with PHP

I'm trying to read the text from this image:
I want to read the price, e.g. "EUR42721.92"
I tried these libraries:
How to Create a PHP Captcha Decoder with PHP OCR Class: Recognize text & objects in graphical images - PHP Classes
phpOCR: Optical Character Recognizer written in PHP
But they don't work. How can I read the text?
Try this (it worked with me):
$imagick = new Imagick($filePath);
$size = $imagick->getImageGeometry();
$width = $size['width'];
$height = $size['height'];
unset($size);
$textBottomPosition = $height-1;
$textRightPosition = $width;
$black = new ImagickPixel('#000000');
$gray = new ImagickPixel('#C0C0C0');
$textRight = 0;
$textLeft = 0;
$textBottom = 0;
$textTop = $height;
$foundGray = false;
for($x= 0; $x < $width; ++$x) {
for($y = 0; $y < $height; ++$y) {
$pixel = $imagick->getImagePixelColor($x, $y);
$color = $pixel->getColor();
// remove alpha component
$pixel->setColor('rgb(' . $color['r'] . ','
. $color['g'] . ','
. $color['b'] . ')');
// find the first gray pixel and ignore pixels below the gray
if( $pixel->isSimilar($gray, .25) ) {
$foundGray = true;
break;
}
// find the text boundaries
if( $foundGray && $pixel->isSimilar($black, .25) ) {
if( $textLeft === 0 ) {
$textLeft = $x;
} else {
$textRight = $x;
}
if( $y < $textTop ) {
$textTop = $y;
}
if( $y > $textBottom ) {
$textBottom = $y;
}
}
}
}
$textWidth = $textRight - $textLeft;
$textHeight = $textBottom - $textTop;
$imagick->cropImage($textWidth+10, $textHeight+10, $textLeft-5, $textTop-5);
$imagick->scaleImage($textWidth*10, $textHeight*10, true);
$textFilePath = tempnam('/temp', 'text-ocr-') . '.png';
$imagick->writeImage($textFilePath);
$text = str_replace(' ', '', shell_exec('gocr ' . escapeshellarg($textFilePath)));
unlink($textFilePath);
var_dump($text);
You need ImageMagick extension and GOCR installed to run it.
If you can't or don't want to install the ImageMagick extension, I'll send you a GD version with a function to calculate colors distances (it's just an extended Pythagorean Theorem).
Don't forget to set the $filePath value.
The image shows that it looks for a gray pixel to change the $foundGray flag.
After that, it looks for the first and last pixels from the left and from the top.
It crops the image with some padding, the resulting image is resized and it's saved to a temporary file. After that, it's easy to use gocr (or any other OCR command or library). The temporary file can be removed after that.
Improve the quality of the image of the numbers before you start the OCR. Use a drawing program to improve the quality (bigger size, straight lines).
You can either modify the PHP scripts and adapt the pattern recognition to your needs.
https://github.com/ogres/PHP-OCR/blob/master/Image2String.php
Or try out other OCR tools:
https://github.com/thiagoalessio/tesseract-ocr-for-php

IMagick function to cut an image into roughly equally-sized tiles

I'm trying to use the IMagick PHP wrapper to assist in chopping a specified image into a set of tiles (the number of which is variable).
In the ImageMagick documentation there is reference to the -crop operator accepting an optional flag of # that will instruct it to cut an image into "roughly equally-sized divisions" (see here), solving the problem of what to do when the image size is not an exact multiple of the desired tile size.
Does anyone know if there is a way to leverage this functionality in the IMagick PHP wrapper? Is there anything I can use besides cropImage()?
I had to do the same thing (if I'm reading your question correctly). Although it does use cropImage...
function slice_image($name, $imageFileName, $crop_width, $crop_height)
{
$dir = "dir where original image is stored";
$slicesDir = "dir where you want to store the sliced images;
mkdir($slicesDir); //you might want to check to see if it exists first....
$fileName = $dir . $imageFileName;
$img = new Imagick($fileName);
$imgHeight = $img->getImageHeight();
$imgWidth = $img->getImageWidth();
$crop_width_num_times = ceil($imgWidth/$crop_width);
$crop_height_num_times = ceil($imgHeight/$crop_height);
for($i = 0; $i < $crop_width_num_times; $i++)
{
for($j = 0; $j < $crop_height_num_times; $j++)
{
$img = new Imagick($fileName);
$x = ($i * $crop_width);
$y = ($j * $crop_height);
$img->cropImage($crop_width, $crop_height, $x, $y);
$data = $img->getImageBlob();
$newFileName = $slicesDir . $name . "_" . $x . "_" . $y . ".jpg";
$result = file_put_contents ($newFileName, $data);
}
}
}

Categories