PythonMagick. All black image bug - imagemagick

I use PythonMagick in my project. When i convert SVG to JPG in command line like "convert x.svg x.jpg" it's ok. When i use PythonMagick i get all black image. I'm confused cuz i have that error only at 2 of 4 computers. They all have approximately similar libraries and OS ubuntu 16-18. Maybe someone can give me some tips what i do wrong. Here is my code.
tmp = tempfile.NamedTemporaryFile(delete=False)
blob = PythonMagick.Blob()
img = PythonMagick.Image('x.svg')
img.composite(img, 0, 0, PythonMagick.CompositeOperator.SrcOverCompositeOp)
img.write(blob, 'jpg')
tmp.write(blob.data)

Related

Strange bug involving string comparison in Lua

I am trying to create a program that scrapes images from the web in Lua. A minor problem is that images sometimes have no extension or incorrect extensions. See this animated "jpeg" for example: http://i.imgur.com/Imvmy6C.jpg
So I created a function to detect the filetype of an image. It's pretty simple, just compare the first few characters of the returned image. Png files begin with PNG, Gifs with GIF, and JPGs with the strange symbol "╪".
It's a bit hacky since images aren't supposed to be represented as strings, but it worked fine. Except when I actually ran the code.
When I enter the code into the command line it works fine. But when I run a file with the code in it, it doesn't work. Weirder, it only fails on jpegs. It still correctly recognizes PNGs and GIFs.
Here is the minimal code necessary to reproduce the bug:
http = require "socket.http"
function detectImageType(image)
local imageType = "unknown"
if string.sub(image, 2, 2) == "╪" then imageType = "jpg" end
return imageType
end
image = http.request("http://i.imgur.com/T4xRtBh.jpg")
print(detectImageType(image))
Copy and pasting this into the command line returns "jpg" correctly. Running this as a file returns "unknown".
I am using Lua 5.1.4 from the Lua for Windows package, through powershell, on Windows 8.1.
EDIT:
Found the problem string.byte("╪") returns 216 on the command line and 226 when run as a file. I have no idea why, maybe different encodings for lua and powershell?
This line solves the problem:
if string.byte(string.sub(image, 2, 2)) == 216 then imageType = "jpg" end
I think it's because when you're saving your file you're saving it as a different encoding so the ╪ character may be translated to another character. It's more robust to convert it to the byte code:
http = require "socket.http"
function detectImageType(image)
local imageType = "unknown"
if string.byte(image, 2) == 216 then imageType = "jpg" end
return imageType
end
image = http.request("http://i.imgur.com/T4xRtBh.jpg")
print(detectImageType(image))

MATLAB MSER Feature detection not working

I am using the detectMSERFeatures function in the computer vision toolbox of MATLAB and have been running into a few errors. I have a black and white image that I am reading in to detect the features of, however I want to invert the image before running the feature detection or I am filtering for the red in an image. Therefore, either way I have a binary image that I am trying to use in detectMSERFeatures. I know that does not work, but I have tried several conversions to a usable format and none of them have seemed to work. detectMSERFeatures will pick up features if I use rgb2gray on the original image, but not if I try to convert it. Here is everything I have tried so far:
Target1=imread('Decal0.JPG');
Target1bw=~im2bw(Target1);
Target=uint8(Target1bw);
[m,n]=size(Target);
regionsTarget = detectMSERFeatures(Target, 'MaxAreaVariation',0.15,...
'ThresholdDelta',15, 'RegionAreaRange',[10000 (m*n)/2]);
Target1=imread('Decal0.JPG');
Target1bw=~im2bw(Target1);
Target=im2double(Target1bw);
regionsTarget = detectMSERFeatures(Target, 'MaxAreaVariation',0.15,...
'ThresholdDelta',15, 'RegionAreaRange',[10000 (m*n)/2]);
Target1=imread('Decal0.JPG');
Target1bw=~im2bw(Target1);
Target2=255*Target1bw;
[m,n]=size(Target2);
Target3=zeros(m,n,3);
Target3(:,:,1)=Target2;
Target3(:,:,2)=Target2;
Target3(:,:,3)=Target2;
Target3=uint8(Target3);
Target=rgb2gray(Target3);
regionsTarget = detectMSERFeatures(Target, 'MaxAreaVariation',0.15,...
'ThresholdDelta',15, 'RegionAreaRange',[10000 (m*n)/2]);
What have I done incorrectly?
I brought the question up to Mathworks and it was a bug in MATLAB. Here is their response:
"We have detected a bug in detectMSERFeatures when it handles binary images. A workaround would be is to use regionprops to detect the regions for binary images. Then, MSERRegions can be constructed as follows:
props = regionprops(im2bw(newGrayTarget),'PixelList');
pixlist = {}
for i = 1:numel(props)
pixlist = [pixlist; int32(props(i).PixelList)]; end
r = MSERRegions(pixlist);
Thanks for the help!

Why Typo3 generates poor quality by convert PNG to PNG with imagemagick?

All my sites works fine, after some updates in the last weeks I realize that the quality of PNG are very bad. I use Typo3 4.5.27 and imagemagick 6.6.0.4, Typo3 called following command:
/usr/local/bin/convert -strip -geometry 150x120! /var/www/introductionpackage-4.5.27/typo3/sysext/install/imgs/jesus2_transp.png[0] /var/www/introductionpackage-4.5.27/typo3temp/pics/install_scale_png.png
This is the output of this command
And this is the refference Image:
Can anybody explain what is wrong? Any suggestion to solve or debug the problem?
I try to update the imagemagick to current version but I still have this issue.
This is GFX section in localconf
$TYPO3_CONF_VARS['GFX']['gdlib_2'] = '0';
$TYPO3_CONF_VARS['GFX']['im_combine_filename'] = 'composite';
$TYPO3_CONF_VARS['GFX']['im_version_5'] = 'im6';
$TYPO3_CONF_VARS['GFX']['im_path_lzw'] = '/usr/local/bin/';
$TYPO3_CONF_VARS['GFX']['im_imvMaskState'] = '1';
$TYPO3_CONF_VARS['GFX']['im_negate_mask'] = '0';
$TYPO3_CONF_VARS['GFX']['im_path'] = '/usr/local/bin/';
$TYPO3_CONF_VARS['GFX']['im_stripProfileCommand'] = '-strip';
$TYPO3_CONF_VARS['GFX']['png_truecolor'] = '1';
$TYPO3_CONF_VARS['GFX']['im_v5effects'] = '0';
$TYPO3_CONF_VARS['GFX']['gdlib_png'] = '1'
Under Basic Configuration of Typo3 is following Content under GDLIB Section:
since the branch from ImageMagick many improvements have been made. It can also be installed over ftp if there is no shell access. http://wiki.typo3.org/GraphicsMagick

Converting PDF to PNG with transparent background

We have a Ruby on Rails application that needs to convert a PDF into a PNG with a transparent background. We're using rmagick 2.13.1. On our development machines the following code works exactly how we want it.
pages = Magick::Image.from_blob(book.to_pdf.render){ self.density = 300 }
page = pages[0]
image_file = Tempfile.new(['preview_image', '.png'])
image_file.binmode
image_file.write( page.to_blob { |opt| opt.format = "PNG" } )
We thens save the image_file and all is peachy. When we deployed to a review server on Heroku, though, the generated image has a white background. It turns out that Heroku's cedar stack is using imagemagick ImageMagick 6.5.7-8 2010-12-02 where we're using ImageMagick 6.7.5-7 2012-05-08 on our development machines.
I've scoured the net for older posts that might apply to the older version to try and figure out how to generate the transparent PNGs. It's surely supported, but, so far I haven't been able to figure out the right combination of settings.
To verify that it wasn't the PDF generation that was the problem, I downloaded a PDF generated on Heroku and successfully converted it using the above code (slightly modified to read the file in instead of generate it) to a transparent PNG.
Some of the things I've tried in various combinations are:
page.matte = true
page.format = "PNG32"
page.background_color = "none"
page.transparent_color = "white"
page.transparent("white")
So, the question is "is this possible?". If so, which settings do I need to set on the image before writing it out?
I'm also investigating including a compiled binary of a more up to date Imagemagick on Heroku.
Any help is appreciated.
This should no longer be an issue, as Heroku has ImageMagick versions 6.7-6.9 on their various stacks.

How can I catch corrupt JPEGs when loading an image with imread() in OpenCV?

OpenCV says something like
Corrupt JPEG data: premature end of data segment
or
Corrupt JPEG data: bad Huffman code
or
Corrupt JPEG data: 22 extraneous bytes before marker 0xd9
when loading a corrupt jpeg image with imread().
Can I somehow catch that? Why would I get this information otherwise?
Do I have to check the binary file on my own?
OpenCV (version 2.4) does not overwrite the basic error handling for libjpeg, making them 'uncatchable'. Add the following method to modules/highgui/src/grfmt_jpeg.cpp, right below the definition of error_exit():
METHODDEF(void)
output_message( j_common_ptr cinfo )
{
char buffer[JMSG_LENGTH_MAX];
/* Create the message */
(*cinfo->err->format_message) (cinfo, buffer);
/* Default OpenCV error handling instead of print */
CV_Error(CV_StsError, buffer);
}
Now apply the method to the decoder error handler:
state->cinfo.err = jpeg_std_error(&state->jerr.pub);
state->jerr.pub.error_exit = error_exit;
state->jerr.pub.output_message = output_message; /* Add this line */
Apply the method to the encoder error handler as well:
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = error_exit;
jerr.pub.output_message = output_message; /* Add this line */
Recompile and install OpenCV as usual. From now on you should be able to catch libjpeg errors like any other OpenCV error. Example:
>>> cv2.imread("/var/opencv/bad_image.jpg")
OpenCV Error: Unspecified error (Corrupt JPEG data: 1137 extraneous bytes before marker 0xc4) in output_message, file /var/opencv/opencv-2.4.9/modules/highgui/src/grfmt_jpeg.cpp, line 180
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
cv2.error: /var/opencv/opencv-2.4.9/modules/highgui/src/grfmt_jpeg.cpp:180: error: (-2) Corrupt JPEG data: 1137 extraneous bytes before marker 0xc4 in function output_message
(I've submitted a pull request for the above but it got rejected because it would cause issues with people reading images without exception catching.)
Hope this helps anyone still struggling with this issue. Good luck.
It could be easier to fix the error in the file instead of trying to repair the loading function of OpenCV. If you are using Linux you can use ImageMagick to make reparation to a set of images (is usual to have it installed by default):
$ mogrify -set comment 'Image rewritten with ImageMagick' *.jpg
This command changes a property of the file leaving the image data untouched. However, the image is loaded and resaved, eliminating the extra information that causes the corruption error.
If you need more information about ImageMagick you can visit their website: http://www.imagemagick.org/script/index.php
You cannot catch it if you use imread(). However there is imdecode() function that is called by imread(). Maybe it gives you more feedback. For this you would have to load the image into memory on your own and then call the decoder.
It boils down to: You have to dig through the OpenCV sources to solve your problem.
i had to deal with this recently and found a solution over here
http://artax.karlin.mff.cuni.cz/~isa_j1am/other/opencv/
i just need to make 2 edits # $cv\modules\highgui\src\grfmt_jpeg.cpp.
--- opencv-1.0.0.orig/otherlibs/highgui/grfmt_jpeg.cpp 2006-10-16 13:02:49.000000000 +0200
+++ opencv-1.0.0/otherlibs/highgui/grfmt_jpeg.cpp 2007-08-11 09:10:28.000000000 +0200
## -181,7 +181,7 ##
m_height = cinfo->image_height;
m_iscolor = cinfo->num_components > 1;
- result = true;
+ result = (cinfo->err->num_warnings == 0);
}
}
## -405,8 +405,9 ##
icvCvt_CMYK2Gray_8u_C4C1R( buffer[0], 0, data, 0, cvSize(m_width,1) );
}
}
- result = true;
+
jpeg_finish_decompress( cinfo );
+ result = (cinfo->err->num_warnings == 0);
}
}
I am using opencv python package to read some image and also met this error message. This error can not be catch by Python. But if you want to find which image is corrupted without recompiling opencv as #Robbert suggested, you can try the following method.
First, you can pinpoint the directory where the corrupt images reside, which is fairly easy. Then you go to the directory, and use mogrify command line tool provided by ImageMagick to change the image meta info, as suggest by #goe.
mogrify -set comment "errors fixed in meta info" -format png *.jpg
The above command will convert the original jpg image to png format and also clean the original image to remove errors in meta info. When you run mogrify command, it will also output some message about which image is corrupted in the directory so that you can accurately find the corrupted image.
After that, you can do whatever you want with the original corrupted jpg image.
Any one stumbles upon this post and reads this answer.
I had to get hold of a corrupted image file.
These websites can help you corrupt your file
Corrupt a file - The file corrupter you were looking for!
CORRUPT A FILE ONLINE
Corrupt my File
First and the third website was not that much useful.
Second website is interesting as I could set the amount of file that I need to corrupt.
OpenCV version I used here is 3.4.0
I used normal cv2.imread(fileLocation)
fileLocation Location of corrupted image file
OpenCV didn't show any error message for any of the corrupted files used here
First and Third website only gave one file and both had None stored in them, when I tried to print them
Second website did let me decide the amount of file that was needed to be corrupted
Corruption% Opencv message on printing the image
4% None
10% None
25% None
50% None Corrupt JPEG data: 3 extraneous bytes before marker 0x4f
75% None Corrupt JPEG data: 153 extraneous bytes before marker 0xb2
100% Corrupt JPEG data: 330 extraneous bytes before marker 0xc6 None
I guess the only check we have to make here would be
if image is not None:
Do your code or else pop an error
You can redirect stderr to a file, then after imread, search for the string "Huffman" inside that file. After searching the file, empty it. It works for me and now I am able to discard corrupted images and just process good ones.
If you load your image with imdecode, you can check errno :
std::vector<char> datas();
//Load yout image in datas here
errno = 0;
cv::Mat mat = cv::imdecode(datas, -1);
if (errno != 0)
{
//Error
}
(tested on OpenCV 3.4.1)
I found that the issue is in libjpeg. If OpenCV uses it, it gets error
Corrupt JPEG data: 22 extraneous bytes before marker 0xd9
You can try my solution to solve it. It disables JPEG during compilation. After that OpenCV cannot read/write, but it works.
cmake -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_SHARED_LIBS=OFF -D BUILD_EXAMPLES=OFF -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D WITH_JPEG=OFF -D WITH_IPP=OFF ..
I found an easy solution without the need to recompile openCV.
You can use imagemagick to detect the same errors, however it returns an error as expected. See the description here: https://stackoverflow.com/a/66283167/2887398

Resources