ruby rmagick压缩和转换png到jpg

eanckbw9  于 2022-11-22  发布在  Ruby
关注(0)|答案(2)|浏览(213)

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!
sgtfey8w

sgtfey8w1#

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.

7y4bm7vi

7y4bm7vi2#

我尝试了另一个答案,但我仍然对透明度有问题。这里的代码对我来说工作得很好:

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" )

这个想法是首先创建一个imageList,然后加载PNG图像到其中,然后添加一个新的图像到该列表,并设置其背景为白色。然后只需颠倒列表的顺序,然后将图像列表扁平化为一个单一的图像。要添加压缩,只需做自我。质量的事情从上面的答案。

相关问题