4

次の PHP/ImageMagick コードを Ruby RMagick に変換することに失敗しています (将来のユーザーが管理しやすくし、実際に何をしているのかを理解するため):

$output = array();
$returnValue = 0;
$pngFiles = $myDir->find("/.png$/i");
foreach($pngFiles as $pngFile) {
   $cmd = 'convert '.$pngFile->path.' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info:'
   exec($cmd, $output, $returnValue);
   if($output[0] != 1) {
      logMessage("PNG file contains some alpha transparency and will not be modified");
   }
}

ここまでで、convert-command が何をしているかはある程度理解できたと思いますが、それを RMagick に翻訳することで、それを再考する必要があります。

例:が のPNG に$output[0] != 1 ある場合 があるのに、RMagickは常にのPNGにあるのはなぜですか? 何か不足していますか?true$myDirImage.alpha? true$myDir

誰かが convert-command が正確に何をしているのか(式を含む)を説明できれば、私を軌道に戻すための最良の方法だと思います%[fx:u.a]

更新: その間、この情報が必要なスクリプトを作成しました。参考になる場合は、Github で確認してください。

4

5 に答える 5

5

The code checks to see if a particular image contains transparency.

-format '%[fx:u.a]' info:

This instructs image magick to check the first image u, the alpha channel of that a and output info on it, it will return 0 if the top-left pixel is transparent and non-zero if not I think. That is why the image is being resized to 1x1, so that only a single pixel needs to be consulted. The -channel o is the opacity channel.

So the code in English would read, cycle through all PNG files, look at the alpha channel (opacity) only, resize to a single pixel and see if it's transparent. Hence the echo message.

Unfortunately I do not know Ruby, or RMagick, but a quick look at the API seems to suggest using image.channel(AlphaChannel) to get the alpha channel (AlphaChannel is a ChannelType value, not sure if you have to specify ChannelType.AlphaChannel), then follow with .resize(1,1) to get the size down, and finish with either .pixel_color(0,0) or .get_pixels(0,0,1,1) to get the Pixel object back (get_pixels() returns an array), which I believe has an opacity attribute. However, the channel() command changes the RGB values to the value of the channel selected, and I'm not sure it preserves the opacity channel so you might just need to look at red forinstance, or omit the .channel() call entirely - though I do not know if that would disrupt the result offhand.

Perhaps if Ruby supports decent functional programming approaches.

image.channel(AlphaChannel).resize(1,1).pixel_color(0,0).red

or this if pixel_color() does not return the opacity for some reason

image.channel(AlphaChannel).resize(1,1).get_pixels(0,0,1,1)[0].red

Without the channel() calls it would be:

image.resize(1,1).pixel_color(0,0).opacity

or

image.resize(1,1).get_pixels(0,0,1,1)[0].opacity

Again, my Ruby is non-existent, so you may have to rearrange those a lot, but the primitives are there.

References

  1. RMagick Documentation
  2. ImageMagick 'fx' escapes
  3. ImageMagick -channel options
于 2010-11-20T19:20:29.827 に答える
1

これに対する解決策をまだ探している人のためにこれを投稿すると、rmagickここで説明されている宝石を使用してルビーでこれを行う方法がありますhttps://stackoverflow.com/a/41282162/1975112

于 2016-12-22T11:33:13.557 に答える
0

表示するphpコード(実際にはシェルで変換するための作業を送信するだけです)は、画像にアルファチャネルがあるかどうかを確認せず、指定されたファイルを取得してオンにします。すでにファイルが存在する場合、ファイルの変更はありませんが、変換はステータスに基づいて決定を行うように求められません。先に進んでチャネルを追加してください。

于 2010-11-09T14:25:30.940 に答える
0

コマンドだけをコピーして system で呼び出さなかったのはなぜですか?

宝石は必要ありません...質問はありません。コードはほとんど同じに見えるはずです。

編集: RMagic は imagemagic のみをラップするため、すでに imagmagic コマンド文字列がある場合に rmagic を気にする必要はありません。

于 2010-11-14T16:07:01.137 に答える
0

Ruby のコードを 1 行もコーディングしたことはありませんが、PHP スクリプトの部分的なリメイクを次に示します。

require 'find'

pngFiles = Dir.glob("*.png")

Find.find('./') do |f|
  if system 'convert ' + f + ' -resize 1x1 -alpha on -channel o -format "%[fx:u.a]" info' do
    print "PNG file contains some alpha transparency and will not be modified"

チェックする必要があるのはアルファチャンネルだけで、複雑なものすべてではないと思います. 詳細については、このページを参照してください: http://www.imagemagick.org/script/escape.php。これには%A演算子があり、アルファ チャネルに関する情報を出力します。

于 2010-11-19T04:08:18.250 に答える