5

RailoでImageNew(および関連)を使用して画像を作成しています。これは、内部でJAIを使用しています。

画像を保存すると、24ビットのPNGが表示されますが、必要なのは8ビットだけです。(グラフィックエディタを使用してファイルを8ビットで再保存するだけで、4分の1から2分の1バイトになります。)

ImageWriteはPNGビット深度に関する機能を提供していません。また、JAI自体でこれを行う詳細も見つかりません(http://jai-core.dev.java.net/のDNSエラーが発生します)

アップデート:

Quantize ImageFilterを使用すると、色の数を256に減らすことができます。これにより、ファイルサイズが大幅に削減されますが(手動で処理する場合ほどではありません)、24ビット/パレットなしのPNGファイルになります。残念ながら、それはまた、私が保存する(または少なくとも再適用する)必要がある透明性を削除します。

これが生成するファイルを取得してOptiPNG(ロスレスPNGオプティマイザー)で実行すると、インデックス付きの8ビットファイルが生成され、かなりの数のバイトが削減され、許容可能なファイルサイズが得られます。

したがって、パズルの残りのステップ: ImageFilterが透明度を削除した後、透明度を再適用するにはどうすればよいですか(または、削除されないようにすることをお勧めします)。

Image.replace('white','transparent')Railo / Javaベースのソリューションとして、またはクロスプラットフォームのコマンドラインツールとして実行する方法が必要だと思います。

4

3 に答える 3

2

さて、私は許容できる結果を生み出す実用的なソリューションを持っています-最終的なファイルは私の元の手動プロセスよりもわずかに小さいですが、視覚的に区別できません。

このソリューションは、私が望むほどクロスプラットフォームではありませんが(OptiPNG用のLinuxバイナリを検索/ビルドする必要があります)、それでも十分なソリューションです。

リーが質問のコメントで示唆したように、私が使用したのは色を減らすための量子化器であり、次にMapColorsFilterを使用して量子化器が透明性を壊すという事実を修正し、最後にOptiPNGを使用して結果のファイルを適切なサイズに圧縮します。

関連するコードは次のとおりです。

<cfscript>
    var Filename = './filename.png'
    var MyImage = NewImage(Filename)

    ImageFilter(MyImage,'quantize',{numColors:256,dither:false})

    // ImageFilter(MyImage,'MapColors',{oldColor:'white',newColor:'ffffff00'})
    var TransImage = ImageMapColors(MyImage,'white','ffffff00')

    ImageWrite( TransImage , Filename )
</cfscript>

<cfexecute
    name      = "#Variables.OptiPngExecutable#"
    arguments = "-o9 #Filename#"
    timeout   = 30
/>

現在、MapColorsフィルターのRailoのImageFilterにバグがあるため、フィルターに直接アクセスする必要がありました。これを回避するために使用したコードは次のとおりです。

<cffunction name="ImageMapColors" output=false >
    <cfargument name="Image" rtype="Image" required />
    <cfargument name="Old"   type="String" required />
    <cfargument name="New"   type="String" required />

    <cfset var ObjKey = 'ColorReplacer_#Arguments.Old#_#Arguments.New#' />

    <cfif NOT StructKeyExists(Variables,ObjKey)>
        <cfset var Old = createObject('java','railo.commons.color.ColorCaster').toColor(Arguments.Old) />
        <cfset var New = createObject('java','railo.commons.color.ColorCaster').toColor(Arguments.New) />
        <cfset Variables[ObjKey] = createObject("java","railo.runtime.img.filter.MapColorsFilter")
            .init(Old.getRGB(),New.getRGB()) />
    </cfif>

    <cfreturn ImageNew( Variables[ObjKey].filter(ImageGetBufferedImage(Arguments.Image),{}) ) />
</cffunction>
于 2012-09-05T23:14:30.487 に答える
0

pngquantwithcfexecuteあなたのニーズを満たすはずです。

于 2012-09-04T18:14:55.140 に答える
-1

の「品質」属性を使用して最初にJPEGとしてImageWrite()保存し、次にPNGとして保存する中間ステップを使用してみましたか?ちょっとした考え。使用を推測する.3.4、値として機能する可能性がありますか?

于 2012-09-04T00:46:24.420 に答える