Reputation: 21603
I am trying to compress a png and save it as jpg:
i = Image.read("http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png").first
it's size is 799 kb:
http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png=>e2558b0d34221d3270189320173dabc2.png PNG 640x639 640x639+0+0 DirectClass 8-bit 799kb
I set the format to jpeg and quality to 10 (i.e very poor quality so file size should be greatly reduced):
i.format = 'JPEG'
i.write("itest10.png") { self.quality = 10 }
The size actually increases to 800kb!
=> http://ds4jk3cl4iz0o.cloudfront.net/e2558b0d34221d3270189320173dabc2.png=>itest40.png PNG 640x639 640x639+0+0 DirectClass 8-bit 800kb
1) Why?
2) How can I compress the photo so the size is < 150kb ?
Thanks!
Upvotes: 3
Views: 6960
Reputation: 27227
The use of '.png' extension will change the format back to PNG on the call to write.
There are two possible solutions.
First, I'd recommend using the normal file extension for your format if possible, because a lot of computer systems will rely on that:
i = Image.read( 'demo.png' ).first
i.format = 'JPEG'
i.write( 'demo_compressed.jpg' ) { |image| image.quality = 10 }
If this is not possible, you can set the format inside the block passed to write, and this will apply the format after the extension has been processed:
i = Image.read( 'demo.png' ).first
i.write( 'demo_compressed.png' ) do |image|
image.format = 'JPEG'
image.quality = 10
end
In both the above cases, I get the expected high compression (and low quality) jpeg format image.
This has been updated due to recent RMagick changes (thanks to titan
for posting comment). The orginal code snippets were
i.write( 'demo_compressed.jpg' ) { self.quality = 10 }
and
i.write( 'demo_compressed.png' ) do
self.format = 'JPEG'
self.quality = 10
end
These may still work in older RMagick installations.
Upvotes: 10
Reputation: 69
I tried the other answer and I was still having issues with the transparency. This code here work fine for me:
img_list = Magick::ImageList.new
img_list.read( 'image.png' )
img_list.new_image( img_list.first.columns, img_list.first.rows ) {
self.background_color = "white"
}
imageJPG = img_list.reverse.flatten_images
imageJPG.write( "out.jpg" )
The idea is first create an imageList then load the PNG image into it and after that add a new image to that list and set its bg to be white. Then just reverse the order of the list then flatten the image list into a single image. To add compression just do the self.quality thing from the above answer.
Upvotes: 4