- PR -

アプレットからImageIOでPNG画像をreadするとエラー

1
投稿者投稿内容
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-01 11:01
以下のソースコードでアプレットからImageIOを使ってpng画像を読もうとすると以下のよ
うなエラーが出ます。
jpegだと問題ありません。画像ファイルが壊れているのかと思い、エクスプローラから直
接 html を起動してWebサーバを経由せずにローカルでアプレットを起動したところ問題
ありません。
サーバ経由でもたまに正しく処理され画面に表示されるときもあります。
Apacheのログを見てみたところ、正常に表示されたときは GET要求の結果のサイズが画像
ファイルと同じサイズですが、正しくないときはサイズが画像サイズに満たないようなロ
グがのこっていました。

ファイルサイズが大きいから読み込めていないのかと思い、5MB程度のJPEGとPNGをそれ
ぞれ読み込んでみると、JPEGでは問題ないのですが、PNGだとNGです。

同様の問題に遭遇して解決されかたはいらっしゃいませんか?よろしくおねがいします。

※ちなみに、JDK1.4.0のときに、アプレットからImageIOで画像をreadしたとき、セキュ
リティエラーが発生しており、それはImageIOが画像読み込み時にローカルディスクをテ
ンポラリ(キャッシュ?)として使用しようとする仕様(バグ?)になっていてエラーで
落ちていました。JDK1.4.1_01では改善されているとのことで、現在はそれを入れており、]その問題は出なくなりました。

<環境>
・Windows2000(sp2) ※Linuxでも同様であった
・Apache 1.3
・JDK 1.4.1_01

<ソース>
import javax.swing.*;
import java.applet.*;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;

public class TestApplet extends JApplet implements ActionListener{
JButton btnRead = new JButton("Read");
JLabel lblImage = new JLabel();
BufferedImage img;
public void init(){
Container cont = getContentPane();
JPanel pnl = new JPanel();
pnl.add(btnRead);
cont.setLayout(new BorderLayout());
cont.add(pnl,BorderLayout.NORTH);
cont.add(lblImage,BorderLayout.CENTER);
btnRead.addActionListener(this);
}

public void actionPerformed(ActionEvent event){
Object obj = event.getSource();
if( obj == btnRead ){
readImage();
}
}

public void readImage(){
URL u;
try{
u=new URL(this.getDocumentBase(),"salt_lake.png");
InputStream inStream = new BufferedInputStream(u.openStream());
img = ImageIO.read(inStream);
lblImage.setIcon( new ImageIcon( img ) );
}catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}


<エラー>
avax.imageio.IIOException: Unknown row filter type (= 11)!

at com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1196)

at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1276)

at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1362)

at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1530)

           ・
           ・
           ・
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-02 23:06
画像サイズを小さ目のもの(118KB程度)のものでテストしてみました。
apacheのログは以下のようになっていました。(一部を抜粋)

なぜか、まずjavax.imageio.spiパッケージをwebサーバから取得しようとしています。
画像が正しく表示されるときは読み込みサイズは画像サイズと同じサイズ(118827)でログが
残っています。
NGのときは、読み込みサイズはなぜか8KBの倍数サイズ(たまたま?)でログが残っており、
HTTPステータスコードはOK(成功)で記録されています。

なぜか、webサーバ経由のpng画像はImageIOではすべてのデータを読めてなさそうです。

"HEAD /META-INF/services/javax.imageio.spi.ImageTranscoderSpi HTTP/1.1" 404 0
"HEAD /META-INF/services/javax.imageio.spi.ImageInputStreamSpi HTTP/1.1" 404 0
"HEAD /META-INF/services/javax.imageio.spi.ImageWriterSpi HTTP/1.1" 404 0
"HEAD /META-INF/services/javax.imageio.spi.ImageReaderSpi HTTP/1.1" 404 0
"HEAD /META-INF/services/javax.imageio.spi.ImageOutputStreamSpi HTTP/1.1" 404 0
"GET /original.png HTTP/1.1" 200 118827 ←読み込みOK
"GET /original.png HTTP/1.1" 200 8192 ←読み込みNG
"GET /original.png HTTP/1.1" 200 32768 ←読み込みNG
"GET /original.png HTTP/1.1" 200 16384 ←読み込みNG
"GET /original.png HTTP/1.1" 200 65536 ←読み込みNG
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-03 10:29
com.sun.imageio.plugins.png.PNGImageReaderクラスのdecodePassメソッドの中を確認
したところ、PNGファイルのヘッダからフィルタ形式を取得して、各フィルタの処理のメソッド
を呼び出そうとしているのですが、本来0〜4が入っているはずが255という値が入っていて
エラーを起こしているようです。

http://tech.millto.net/~pngnews/kndh/PngSpec1.2/PNGcontents.html のページの
IHDR イメージヘッダという項目から、何バイト目にフィルタ形式が入っているかがわかっ
たのでバイナリエディタで確認したところ、実際には 0 が入っていました。
したがってファイルは壊れていなく、ブラウザやアプレット、グラフィックエディタなどで
ローカルファイルとしてPNG画像を開くと問題なく表示され、アプレットのWebサーバ経由の
ImageIOで読むとなぜか、255として読み込まれエラーが出ているようです。

maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-03 14:59
以下のホームページの後半に、今回の現象と同じような内容が書いてありました。
http://www.lanset.com/crazy17/jp/lab/png2.htm

Webサーバによっては mimeタイプにpngが登録されていないので、ブラウザによっては正常
に見えない場合があるというような内容でした。これでは?!と思い、早速確認したのです
が、さすがに最新のapacheにはちゃんと登録されてあり、関係なかったようです。

がっくり。

ちなみに、Win2000のIIS5.0でも同様のテストをしてみたのですが、やはり同じように
エラーが発生しており、画像ファイルも全サイズを返していないのにHTTPステータス 200 と
なっていました。

さくらば
大ベテラン
会議室デビュー日: 2002/11/12
投稿数: 145
投稿日時: 2003-03-03 23:00
どうやらライブラリの Bug のようです。
http://developer.java.sun.com/developer/bugParade/bugs/4821108.html

Image I/O の新しいバージョンでも試してみたのですが、だめでした。
http://developer.java.sun.com/developer/earlyAccess/jai_imageio/
maru
ぬし
会議室デビュー日: 2003/01/27
投稿数: 412
投稿日時: 2003-03-04 09:46
記事を見つけてくださってありがとうございました。

先日から、(こちらにも何回か質問させていただきましたが)サーバにある特殊形式の画像を
画質の劣化なくアプレットで読むためにJMagickやTIFFについていろいろ調べて、苦労の末
たどり着いたのがサーバのサーブレットでPNG形式に変換した画像をアプレット側でImageIO
を使って読む方法だったのですがダメなようですね。がっくり。

サーバ側で読み込んだImageオブジェクトをバイト配列でアプレットに渡す方向で考えてみ
ます。
1

スキルアップ/キャリアアップ(JOB@IT)