Java me J2ME-在PhotoShop中创建的PNG未在emulator中显示

Java me J2ME-在PhotoShop中创建的PNG未在emulator中显示,java-me,png,emulation,photoshop,java-wireless-toolkit,Java Me,Png,Emulation,Photoshop,Java Wireless Toolkit,我的midlet显示了一些很好的图像,但没有其他图像 它们都是8位PNG,但没有显示的是我自己在PhotoShop中创建的 所以我想也许我的PhotoShop(CS6)设置是错误的 PNG-8,选择性,扩散,颜色:256,抖动:100%,无光泽:无,网络 捕捉:0%,转换为sRGB:勾选,宽度:48,高度:48,百分比:100%, 质量:双三次 我已经尝试过其中一些设置,但没有效果 有什么想法吗 有一个问题,但这与我的相反,在这种情况下,PhotoShop修复东西,而不是破坏东西 我的代码是 i

我的midlet显示了一些很好的图像,但没有其他图像

它们都是8位PNG,但没有显示的是我自己在PhotoShop中创建的

所以我想也许我的PhotoShop(CS6)设置是错误的

PNG-8,选择性,扩散,颜色:256,抖动:100%,无光泽:无,网络 捕捉:0%,转换为sRGB:勾选,宽度:48,高度:48,百分比:100%, 质量:双三次

我已经尝试过其中一些设置,但没有效果

有什么想法吗

有一个问题,但这与我的相反,在这种情况下,PhotoShop修复东西,而不是破坏东西

我的代码是

image = Image.createImage("/img/loading1.png");
…这是我的堆栈跟踪:

java.io.EOFException
    at javax.imageio.stream.ImageInputStreamImpl.readFully(
ImageInputStreamImpl.java:353)
    at java.io.DataInputStream.readUTF(DataInputStream.java:609)
    at javax.imageio.stream.ImageInputStreamImpl.readUTF(ImageInputStreamImpl.java:332)
    at com.sun.kvem.png.PNGImageReader.parse_iTXt_chunk(PNGImageReader.java:447)
    at com.sun.kvem.png.PNGImageReader.readMetadata(PNGImageReader.java:650)
    at com.sun.kvem.png.PNGImageReader.readImage(PNGImageReader.java:1312)
    at com.sun.kvem.png.PNGImageReader.read(PNGImageReader.java:1582)
    at com.sun.kvem.midp.GraphicsBridge.loadImage(GraphicsBridge.java:2602)
    at com.sun.kvem.midp.GraphicsBridge.createImageFromData(GraphicsBridge.java:2511)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at com.sun.kvem.sublime.MethodExecution.process(MethodExecution.java:42)
    at com.sun.kvem.sublime.SublimeExecutor.processRequest(SublimeExecutor.java:63)
    at javax.microedition.lcdui.Image.createImage(Image.java:315)
问题中的映像确实存在——无论是在项目中还是在构建的jar中

以下是有问题的图像:

根据崩溃日志,J2ME中的PNG解码器在非关键块
iTXt
中出现故障:1

根据,
iTXt
块的文本部分必须是有效的UTF8:

。。。剩余的块数据是主UTF-8文本,根据压缩标志,可以是zlib压缩的,也可以是未压缩的。因为它的长度可以根据区块长度来确定,所以它不是以null结尾的。和其他两个文本块一样,换行符应该用单行换行符(十进制10)表示,不鼓励使用所有其他控制字符(1-9、11-31和127-159)

因此,通常情况下,这表明读取的流不是有效的UTF8文本-它包含的“原始”字节高于普通ASCII范围
0..127
,不符合UTF8规则

我发现示例图像中的情况并非如此。只有一组连续字节构成UTF8代码序列,并且是有效的:

<?xpacket begin="EFBBBF" id=" .. 然后是一个循环,用于读取
utflen
字节(而不是“Unicode字符”)。这对于
iTXt
块是错误的,因为它没有“第一个单词”来表示其长度。纯文本中的字节数可以从区块长度(根据PNG约定,区块长度是不包括长度长的字、
iTXt
签名本身和最终的CRC32代码的总数据长度)减去以零结尾的关键字名称、语言和“翻译的关键字”字符串的长度得出,两个字节表示纯文本的压缩


作为解决方法,从PNG图像中删除
iTXt
块。数据本身——XMP元数据——对于您的目的来说很可能一点也不有趣(但请随意阅读)。如果您的工作流不使用它,它只是一堆无用的未压缩文本,在示例图像中总共981个字节中占据814个字节——高达83%

您可以使用外部实用程序删除无关的数据块;例如,流行的
pngcrush
的命令行是

pngcrush -rem alla -rem text InputFile.png OutputFile.png
(来自)

或者直接从Photoshop:如果您使用“另存为”菜单选项以“常规方式”保存PNG,则元数据将进入,并且没有复选框可以删除它。如果改为使用“为Web和设备保存”,则会出现一个带有许多方便选项的大型对话框,例如标签为“元数据”的下拉列表

选择“全部”,我得到一个更大的文件;我的Photoshop版本创建了大量3K的XMP元数据,包括一个2K的完全空的“填充”块…
选择“Copyright”或“None”最终去掉了所有的crud(可能是因为我没有填写任何版权信息),然后得到了一个169字节长的PNG,其中唯一的元数据是使用的软件称为“AdobeImageReady”


这有点讽刺。根据PNG规范

。。解码器遇到辅助位为1的未知块时,可以安全地忽略该块并继续显示图像。
()

此“辅助位”是区块ID第一个字节的第5位:0(大写)=关键,1(小写)=辅助,即,如果区块ID的第一个字符是大写,PNG读取器必须正确读取和解释其数据,如果不是,则可以无声跳过


因此,从技术上讲,J2ME的作者完全可以忽略这一部分。但是他们把它弄糟了,试图读取它,现在代码在所有程序上崩溃了,这些程序仅仅试图读取png中的图像数据,而这些png恰好包含
iTXt
块。

使用PNGout或Optipng工具在使用前优化png。这些工具去除了所有不必要的数据,并针对J2ME兼容性对它们进行了优化。谢谢,但是知道如何使用它吗??我已经找到了这个教程,但没有一个更明智的。。。我发现另一个教程建议使用
pngout.exe loading1.png loading1out.png
。看起来
iTxt
块中有一些意外的文本。使用Photoshop的Save for Web,您可以选择不包含任何元数据——试试看。@Jongware谢谢-删除元数据就可以了。你想补充一下吗?这样我就可以接受了。
588       public final static String readUTF(DataInput in) throws IOException {
589           int utflen = in.readUnsignedShort();
pngcrush -rem alla -rem text InputFile.png OutputFile.png