さて、私は許容できる結果を生み出す実用的なソリューションを持っています-最終的なファイルは私の元の手動プロセスよりもわずかに小さいですが、視覚的に区別できません。
このソリューションは、私が望むほどクロスプラットフォームではありませんが(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>