I'm trying to create a thumbnail / cutout of a larger image and it works for a large percentage of the time but every now and again I get the following:
Warning: imagecreatefromjpeg(): gd-jpeg, libjpeg: recoverable error: Corrupt
JPEG data: 626 extraneous bytes before marker 0xd9 in code.php on line 5
This is line 5 of "code.php":
$srcImg = imagecreatefromjpeg('5f48ecb107a1e297d23392f703992d60.jpg');
The image displays fine in windows but gd just fails to create the resource so I end up with a blank image (where the cutout section was supposed to go).
For frame of reference this is with regard to car titles and the system has 2784 that worked and only 36 that didn't so not a big deal but it has my curiosity piqued.
It sounds much like this problem reported on another web site, and the PHP bug is ticket #29878 (unavailable when I checked).
Although you should also verify that the image file is a valid, non-corrupt, JPEG image file as well. ImageMagick's identify program can identify if the file is corrupt. One potential problem is a JPEG file that uses CYMK rather than RGB colormap. ImageMagick can also likely let you resave the image to a valid JPEG file if corrupted.
Related
I have an issue with GD not creating a new JPG file, it just fails. No error messages and no indication as to what is happening. This is not new code, it has been in and working for the past six years, but all of a sudden with larger images it has started failing.
As a background this is running on an old server (to be switched off and moved to a new site on PHP8 in a couple of months time) that has PHP5.3.3 with GD version 2.0.34.
The code is creating thumbnails from the high-res image (around 24-30MB) and outputting a series of thumbnails from 150px wide to 1024px wide. It fails on all. I have increased the PHP memory limit on the page to 512MB, and set the GD.JPEG_ignore_warning flag for corrupt JPGs.
But every time with these files, this line:
$src_img = #imagecreatefromjpeg($file_path);
just returns FALSE. But never falls over with an error. The file is definitely there (run the same code with a file of the same name that is <20MB and it works fine) and there is plenty of disc space/memory available for a 60MB file to be processed in memory, so I dont see that that is the issue.
A search of Google, StackOverflow and several other sites has not produced any similar issues.
Can anyone offer any thoughts as to what the issue/solution is? I have been looking at this for two days now, and we need to resolve it - simply using smaller JPG files isn't an option for this.
Thanks to #Lessmore answer above, GD was reporting an invalid JPG file, so a further search revealed this answer on StackOverflow, which solved the problem by reading the JPG from a string, rather than file:
Reading an invalid JPG with GD
Thanks all - as ever!
I am using Imagick to edit and save svg image.
I am getting an error when I save svg image after having croped it.
Here is my code to operate svg images:
$image = new Imagick();
$image->readImage($path1);
$image -> cropImage($rw*11.2, $sw*7.7, 0, 0);
$image->writeImage('Cvilogpdfbackend/core/images/tempimage/'.$targetfile.'.svg');
When i call this function, I am getting bellow error
PHP Fatal error: Uncaught ImagickException: delegate failed
`'potrace' --svg --output '%o' '%i'' #
error/delegate.c/InvokeDelegate/1897 in
/home/civilogc/public_html/resizeimage.php:19 Stack trace:
#0 /home/civilogc/public_html/resizeimage.php(19): Imagick->writeimage('Cvilogpdfbacken...')
#1 {main} thrown in /home/civilogc/public_html/resizeimage.php on line 19
How to solve this issue?
Why would you want to use mainly bitmap/raster based image processing library (ImageMagick) to modify vector SVG images?
Let me first point you to do the right way:
ImageMagick should be mostly used for reading and writing bitmap images and for creating/writing SVG images (and other vector based format if required, e.g. EPS, PDF etc).
Instead of using ImageMagick/Imagick for your conversion (changing vector image to bitmap and back again - losing quality) just read your image for example with this code:
$image = file_get_contents($path1);
$svg_dom = new DOMDocument();
$tmp_obj = $svg_dom->getElementsByTagName("svg")->item(0);
$svg_width = floatval($tmp_obj->getAttribute("width"));
$svg_height = floatval($tmp_obj->getAttribute("height"));
$svg_viewbox = floatval($tmp_obj->getAttribute("vieWBox"));
and then I suggest you just calculate the new viewBox with your cropping adjustment (create a function for that) and set it back, optionally set new width and height as well:
$svg_viewBox = calculateCroppedView($svg_viewbox, $new_width, $new_height, $top, $left);
$tmp_obj->setAttribute("viewBox", $svg_viewBox);
$tmp_obj->setAttribute("width", $new_width."px");
$tmp_obj->setAttribute("height", $new_height."px");
file_put_contents('Cvilogpdfbackend/core/images/tempimage/'.$targetfile.'.svg', $svg_dom->saveXML());
Note: you are not really cropping the SVG image (SVG elements), just changing the view (e.g. zoom) to it. Converting all cut paths, shapes, text etc is possible but would require a lot of coding. Either way the goal is to keep the (vector) image quality.
For an excellent explanation of the SVG viewBox attribute read this section:
https://css-tricks.com/scale-svg/#the-viewbox-attribute
To answer your question:
This error states that ImageMagick in your webserver cannot find or doesn't have installed the (free) potrace software that does the actual vectorization of a bitmap image.
Note: you need to have ImageMagick version 7 since older version just embedded bitmap images and data encoded (base64) string to the SVG image tag or maybe used a weird conversion - depending of ImageMagick version - of converting dots to 1px SVG circle tags. And ImageMagick installed needs to be the same version as Imagick as well for the mentioned reasons.
Potrace software command line is set in delegates.xml of the ImageMagick/Imagick installation and ImageMagick or Imagick needs to find potrace in the PATH (environment variable).
I suggest you to contact your web hosting provider to install Potrace that can be downloaded here:
http://potrace.sourceforge.net/#downloading
And then you'll have to test your script, most likely your web hosting provider will already solve the issue just by installing Potrace. Maybe a path to it will need to be added to a user/system PATH variable and that should practically solve your issue.
If not, you can try to use ImageMagick (convert or now renamed magick, main program) and potrace using exec() command in PHP yet your web hosting must allow that since it's usually forbidden in PHP configuration.
To go for other help:
Well, ask a question here on SO or on ImageMagick support forum that based on their main site forum (where you cannot register anymore) is now here:
https://github.com/ImageMagick/ImageMagick/discussions
In my PHP-FPM log file I have lot's of rows like the following
[18-Sep-2016 03:59:06] WARNING: [pool www] child 5425 said into stderr: "Not a JPEG file: starts with 0x47 0x49"
What does it means?
It is a common error. It looks like you are opening a file with imagecreatefromjpeg, but it is not a jpeg, it is a gif file, take a look at this note concerning starting bytes.
It's most supposely a GIF, as they start with 0x47 0x49. JPG starts with 0xFF 0xD8 0xFF. Have a look at https://en.wikipedia.org/wiki/List_of_file_signatures and reconsider your code: do you want to fail it on such cases (filenames alone are never a guarantee for their content), or do you want to react on it by then guessing its format and trying to parse it as such.
It seems that you are trying to open a jpeg file which is not actually a jpeg or jpg. the file must be of some other format ( png, tiff, bmp or some other) and have been forced renamed as .jpg or .jpeg.
I'm on as following
Ubuntu 12.04 LTS
PHP 5.3.10-1ubuntu3.18 with Suhosin-Patch (cli)
ImageMagick 6.6.9-7
GPL Ghostscript 9.05 (2012-02-08)
my gs is under /usr/bin
I'm converting continuously - PDF to JPG each pdf page to single image. It worked first time for 1-30 sets of PDF but now I'm getting error after 7 sets of PDF being complete
running the PHP script in command line. After converting 5-7 sets of PDF to JPG separate images (about 1000 JPG) i'm getting the following error
PHP Fatal error: Uncaught exception 'ImagickException' with message 'Postscript delegate failed `../books/58/58.pdf': # error/pdf.c/ReadPDFImage/663' in /var/www/mysite/public_html/admin/lib.php:10
Stack trace:
#0 /var/www/mysite/public_html/admin/lib.php(10): Imagick->__construct('../books/58/58....')
#1 /var/www/mysite/public_html/admin/test.php(118): include('/var/www/stagin...')
#2 {main}
thrown in /var/www/mysite/public_html/admin/lib.php on line 10
lib.php has the script to convert the PDF to JPG - code as below
<?php
$file_name = "../books/$book_id/$book_id".'.pdf';
mkdir("../books/$book_id/pages");
// Strip document extension
$file_name = basename($file_name, '.pdf');
// Convert this document
// Each page to single image
$img = new imagick("../books/$book_id/$book_id".'.pdf');
// Set image resolution
// Determine num of pages
$img->setResolution(300,300);
$num_pages = $img->getNumberImages();
// Convert PDF pages to images
for($i = 0;$i < $num_pages; $i++) {
// Set iterator postion
$img->setIteratorIndex($i);
// Set image format
$img->setImageFormat('jpeg');
// Write Images to temp 'upload' folder
$img->writeImage("../books/$book_id/pages/$i".'.jpg');
}
$img->destroy();
?>
After getting the error it stop the converting, but when I run the script again it works for another 5-7 sets of PDF and stop again.
Can anyone please tell me what i'm missing here.
I appreciate your kind help.
Thank you in advance.
As #KenS suggested, this is probably a case where calling GhostScript directly would be better, as it would be both faster, and not crash.
I would suspect that the issue that you're seeing is that some resource is being held open by ImageMagick, and that at some point the processing just starts failing because there is no more of that resource available.
If you wanted to investigate that, strace would be the tool to do it with. However just calling GS directly would allow you to get on to more important stuff.
I have a gallery of JPEG images I'm trying to manage using PHP's GD. One particular JPEG image is giving me trouble. It identifies itself with dimensions of 32,768 x 1,024 pixels. The image is only 1.9 MB on disk. It's handled fine by other image processing tools like Finder and Preview on my Mac, and ImageMagick. Yet, when my system calls imagecreatefromjpeg() on it, I get a classic "Allowed memory size exhausted" fatal exception. I believe the image is corrupted. It's supposed to be a 1024x1024 snapshot of a web page, created with wkhtmltoimage.
Ordinarily the answer to this is to increase PHP's memory_limit. But mine is already big, at 256MB.
Is there anything I can do to preemptively detect this type of image corruption and gracefully handle it? If I add an "#" before the imagecreatefromjpeg() call, PHP merely dies with "500 Internal Server Error" instead. I can't use try/catch either since it's a fatal error.
FWIW, here's how ImageMagick's identify tool describes it:
myimage.jpg JPEG 32768x1024 32768x1024+0+0 8-bit sRGB 1.948MB 0.000u 0:00.000
I suppose I could do if ($width == 32768) { ... }, but that's hackish. There could be an image with that width.
Any other ideas?