I have been trying to convert PDF to JPG images using ImageMagick on CodeIgniter, but the produced image is in low quality and always having black background for some reason (while PDF isn't).
The code I'm using
public function converter($pdf){
$this->load->library('image_lib');
$config = array(
'image_library' => 'imagemagick',
'library_path' => '/usr/bin/convert',
'source_image' => "./pdf/".$pdf,
'new_image' => "./images/a.jpg",
'maintain_ratio' => true,
'width' => 980,
'quality' => '90%',
);
$this->image_lib->initialize( $config );
if ( $this->image_lib->resize( ) ) {
$this->image_lib->clear( );
}
}
Anybody have any idea about what does seem to be wrong here?
You need two things that CodeIgniter probably doesn't support, so you have to use ImageMagick directly.
First, you have to set the resolution of the PDF for a high-quality result. On the ImageMagick command line, this can be done with the -density option. With PHP imagick, use setResolution.
To get rid of the black background, you have to flatten the PDF on a white background first. On the command line, use the options -background white -flatten. With PHP imagick, setImageBackgroundColor and flattenImages should work.
You can set quality and transparency of output picture in prefrences of 'image_lib' library. Please read http://ellislab.com/codeigniter/user-guide/libraries/image_lib.html and look for 'quality', and 'wm_x_transp' options.
I've run into a similar problem, which I solved for myself by calling GhostScript to create a png file (the jpg created wasn't high enough quality):
"gswin64c -r150 -dNOPAUSE -dBATCH -sDEVICE#pngalpha -sOutputFile=" + strTitle + "-%%02d.png " + strTitle + ".pdf"
Then converting the jpgs to pngs (using ImageMagick):
mogrify -format jpg *.png
Related
I'm trying to convert some similar images from gif to png.
You can find two of the pictures here:
https://europa.eu/european-union/about-eu/history/1980-1989_en.
After converting the first gif (for the year 1981), you can see the background colour is the same as before, white, but for the second gif (for the year 1986), the background colour changed to pink. How to fix it?
Below is my code:
file_in = uigetfile('*.*', 'All Files', 'MultiSelect','on');
file_out = cellfun(#(x) cat(2, x(1:(length(x)-3)), 'png'),...
file_in, 'UniformOutput', false);
for i = 1: length(file_in)
[gif,map] = imread (file_in{i});
imwrite (gif, map, file_out{i}, 'Background', [0 0 0]);
end
Matlab have never change the image color after conversion. Thus, if you try to open the 'gif' or 'png' by imshow you will get the same result.
Whatever, if you want to change the background color to white use this code.
For historical reasons we are forced to use Cairo and Imager together.
Converting from Cairo to Imager and converting it back to Imager for some reason makes the color strange.
The reason for converting to Imager again is to combine with another Imager object after this.
# Create a yellow fill image as Cairo object.
# And output as a png file.
my $testSurface = Cairo::ImageSurface->create(
'argb32',
$width,
$height
);
my $testContext = Cairo::Context->create($testSurface);
$testContext->rectangle(0, 0, $width, $height);
$testContext->set_source_rgba(1.0, 1.0, .0, 1);
$testContext->fill();
# This is a yellow png file.
$testSurface->write_to_png("output/fill_yellow.png");
# Convert the Cairo object to an Imager object.
my $testData = $testSurface->get_data;
my $testImager = Imager->new(
xsize => $width,
ysize => $height,
channels => 4,
);
my $testRes = $testImager->read(
data => $testData,
type => "raw",
xsize => $width,
ysize => $height,
raw_datachannels => 4,
raw_storechannels => 4,
raw_interleave => 0,
);
# Output Imager object as a PNG file.
# ! This PNG file becomes blue unexpectedly
$testRes->write(
file => "output/fill_yellow_imager.png",
type => "png"
);
Cairo is using ARGB for its raw format, while Imager is using RGBA. The difference between them is the order that the samples are stored within each pixel. Cairo also uses premultiplied alpha, while Imager uses non-premultiplied alpha. Neither library seems to have any option to change either of these things.
The sample ordering thing could be fixed fairly easily by re-ordering the bytes within the raw image data, but the premultiplication thing starts to get into the territory of not worth bothering with. Therefore I recommend that you simply save a PNG file in Cairo and load it in Imager. It may be slightly slower, but it's easy to understand and recognize that it's correct.
Below: code from a previous version of this answer that recommended swapping the byte order, before I realized about the premultiplied alpha issue:
for (my $i = 0 ; $i < length($testData) ; $i += 4) {
substr($testData, $i, 4,
substr($testData, $i+1, 3) . substr($testData, $i, 1)
);
}
I don't recommend using it.
I'm a graphic designer and often I make websites. I am looking for a script (may ultimately be even software) that finds ONE matching color to the photo. A very good illustration of this is that page: https://unsplash.com/grid If refered your mouse on the picture it shows a matching color. This is a screenshoot that I show this issue: https://dl.dropboxusercontent.com/u/65947165/qu1.png
I would use ImageMagick and find the average colour by resizing the image to 1 pixel x 1 pixel and converting that pixel to text, like this:
convert photo-1414637104192-f9ab9a0ee249.jpg -resize 1x1! -colorspace RGB txt:
# ImageMagick pixel enumeration: 1,1,255,rgb
0,0: (0,21,3) #001503 rgb(0,21,3)
So rgb(0,21,3) is the green leaf with the drop of water from your example. You can have it as sRGB like this:
convert photo-1418479631014-8cbf89db3431.jpg -resize 1x1! txt:
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (141,109,91) #8D6D5B srgb(141,109,91)
If you want it as an image, you would do this:
convert photo-1414637104192-f9ab9a0ee249.jpg -resize 1x1! -scale 1000 output.jpg
This is the first image from your example page...
I don't really speak PHP, but this should be close:
<?php
$image = new Imagick('input.jpg');
$image->resizeImage(1,1,Imagick::FILTER_BOX,1);
$pixel = $image->getImagePixelColor(0,0);
print $pixel->getColorAsString();
$colors = $pixel->getColor();
print_r($colors);
?>
Output
srgb(55.259%,42.2065%,34.9279%)Array
(
[r] => 141
[g] => 108
[b] => 89
[a] => 1
)
I am attempting to do some bulk resizing operations of images using ImageMagick and perlmagick (Image::Magick). All of the images I have as sources are large images and I want to resize them down to various intervals or either height or width. I want to always preserve the aspect ratio.
Given an example image with dimensions of 3840 pixels × 2160 pixels (3840x2160) I want to create the following resized images:
?x1000
?x500
?x100
1600x?
1200x?
800x?
400x?
I can do this very simply using the convert command line utility with the following commands (in order):
convert input_filename.jpg -resize x1000 output_wx1000.jpg
convert input_filename.jpg -resize x500 output_wx500.jpg
convert input_filename.jpg -resize x100 output_wx100.jpg
convert input_filename.jpg -resize 1600 output_1600xh.jpg
convert input_filename.jpg -resize 1200 output_1200xh.jpg
convert input_filename.jpg -resize 800 output_800xh.jpg
convert input_filename.jpg -resize 400 output_400xh.jpg
Since I am attempting to perform these operations in bulk in conjunction with other operations I am attempting to perform these same operations in perl using Image::Magick. I have tried several different methods with the following results:
#METHOD 1
my $image = Image::Magick->new();
$image->Read($input_filename);
$image->Resize(
($width ? ('width' => $width) : ()),
($height ? ('height' => $height) : ()),
);
$image->Write(filename => $output_filename);
This results in images that do not maintain aspect ratio. For example, if a height of 100 is supplied, the output image will be the original width by 100 (3840x100). A comparable effect is had when supplying a width -- the height is maintained, but the aspect ratio is not.
#METHOD 2
my $image = Image::Magick->new();
$image->Read($input_filename);
die "Only one dimension can be supplied" if $width && $height;
$image->Resize(geometry => $width) if $width;
$image->Resize(geometry => "x$height") if $height;
$image->Write(filename => $output_filename);
This results in images that maintain aspect ratio, and if the geometry operation is based on height, the output is exactly what is intended. However, if a width is supplied the output is terribly blurry.
#METHOD 3
`convert "$input_filename" -resize $width "$output_filename"` if $width;
`convert "$input_filename" -resize x$height "$output_filename"` if $height;
This results in images that are all correct, but forks outside of the perl process leading to efficiency issues.
Is there a better way in perl to make this resize operation produce the same results as the command-line convert utility?
My command line utility reports version 6.7.9-10, and Image::Magick reports version 6.79.
Your method #2 is on the right track. To preserve aspect ratio, supply the width and height via the geometry keyword. Your procedure can be made more general by performing the resize in one call instead of two:
$image->Resize(geometry => "${width}x${height}");
This ensures that Resize will only be called once, even if you supply both $width and $height. Just make sure that if either value is not supplied, you set it to the empty string. If you supplied both a width and height to your procedure in method #2, that could have been the cause of the blurriness you saw.
Another possible source of blurriness is the filter used by the resize operator. The best filter to use for a given operation depends on both the color characteristics of the image and the relationship between the original dimensions and the target dimensions. I recommend reading through http://www.imagemagick.org/script/command-line-options.php#filter for information about that. In PerlMagick, you can specify the filter for Resize to use via the filter keyword.
That said, I did not find particular problems with blurriness with images that I tried, so if the problem persists, a test image would be most helpful.
I might be a little late to this party, but as I had a very similar goal - resizing an image and maintaining a balance between image quality and the amount of disc space it takes up - I came up with the following code. I started out with OPs code and followed this very interesting article: https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/
This is the result:
sub optimize_image_size
{
my $imagePath = shift();
my $height = shift(); #720
my $width = shift(); #1080
my $image = Image::Magick->new();
$image->Read($imagePath);
die "Only one dimension can be supplied" if $width && $height;
$image->Thumbnail(geometry => "$width",filter=>'Triangle') if $width;
$image->Thumbnail(geometry => "x$height",filter=>'Triangle') if $height;
$image->Colorspace(colorspace=>'sRGB');
$image->Posterize(levels=>136, dither=>'false');
$image->UnsharpMask(radius=>0.25, sigma=>0.25, threshold=>0.065, gain=>8);
$image->Write(filename => $imagePath
, quality=>'82'
, interlace=>'None'
);
}
At least for me it produces very satisfactory size reduction (my 6MB sample images were reduced to about 90Kb), while keeping a quality similar to Photoshops "for web" settings and of course maintaining aspect ratio no matter if you provide width or height.
Too late for OP but maybe it helps other people.
I am trying to make a partially opaque png using MiniMagick, but I guess what it really boils down to is the syntax for using '-evaluate'
This works in the terminal:
convert input.jpg -alpha on -channel a -evaluate set 25% output.png
But I don't quite understand how to turn it into minimagick code
This is (the latest permutation of) what I'm trying:
require 'mini_magick'
img = MiniMagick::Image.open('input.jpg')
img.combine_options do |mogrify|
mogrify.alpha 'on'
mogrify.channel 'a'
mogrify.evaluate 'set', '25%'
puts mogrify.inspect
end
img.write('output.png')
The inspect output shows that #args is #args=["-alpha", "\"on\"", "-channel", "\"a\"", "-evaluate", "\"set\"", "\"25%\""]
No error messages, but all I get is an identical copy of input.jpg
You are pretty much all the way there except that you also need to let minimagick know that you are outputting in PNG format using:
img.format('png')
Try this instead:
require 'mini_magick'
img = MiniMagick::Image.open('input.jpg')
img.format('png')
img.combine_options do |mogrify|
mogrify.alpha 'on'
mogrify.channel 'a'
mogrify.evaluate 'set', '25%'
end
img.write('output.png')