質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

4103閲覧

byte列をBufferedImage型に変換できません(JAVA)

conderdf

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2017/05/21 07:58

MYSQLに保存した画像のバイト配列を、JAVAでBufferedImage型に変換しようとしているのですが、
ImageIO.read();
を使うと、imageがどうしてもnullになってしまいます。

以下のソースのどこを改善したらよいでしょうか。

try { byte[] buf = ”画像のバイト配列(UTF-8)”; BufferedImage image = ImageIO.read(new ByteArrayInputStream(buf)); }catch (IllegalArgumentException e) { System.out.println(e); e.printStackTrace(); } catch (IOException e) { System.out.println(e); e.printStackTrace(); }

これを実行するとimage=nullになります。
IllegalArgumentException、IOException には引っかかりません。
buf をSystem.out.print();で表示してみると、
[B@583c5c6bと表示されます
Eclipseでbufの中身を見た場合、
[91, 66, 64, 53, 56, 53, 52, 97, 98, 50, 50]となっていました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

上記のデータは16進数で

5b 42 40 35 38 35 34 61 62 32 32

文字として表現すると

[ B @ 5 8 5 4 a b 2 2

質問者さんは

byte[] buf = ”画像のバイト配列(UTF-8)”;

と書かれていますが、上記のデータはbut.toString()とした文字列データをISO8859エンコーディングしたバイト列に見えます。つまりDBからバイナリーデータを取り出した後bufへ正しくその内容を設定できていません。DB上にはBLOBとして格納しているかバイナリーをなんらかのエンコードで文字列へ変換したものを格納していると思います。そのデータの取り出し方に問題があるということだと思います。


追記1: ”画像のバイト配列(UTF-8)”という記述から推測するに、バイナリーデータを文字として扱えると思っておられるようですが、もしそうなら間違いです。バイナリーデータはUTF-8とかISO8859などのいわゆる文字のエンコーディングでは表現できません(してはなりません)。


追記2:回答コメントをよく見たら・・・文字列とbyte[]を連結してますね。Javaでは文字列と文字列以外を'+'で連結すると文字列以外のデータはString.valueOfで文字列へ変換されて連結されてしまいます。せっかくバイナリーデータをbyte[]として用意してもStringとして扱ってしまうと"[B@xxxxx"みたいな意味のない文字列へ変換されてしまいます。

追記1にも書いたのですがバイナリーデータを文字列として扱ってはなりません。明確に区別して処理するようにしてください。

自分はSpring frameworkを一度も使ったことがないのでJdbcTemplateを使ってBLOBを書き込むコードを知りません。素のJDBCとPreparedStatementを使うなら次のようにします。

java

1//カラム定義は id=INT, image=BLOBです 2int id = ...; 3byte[] bytes = ...; 4... 5String sql = "insert into image_table(id,image) values (?,?);"; 6PreparedStatement statement = connection.prepareStatement(sql); 7statement.setInt(1, id); // 1番目のplace holderへintを設定 8statement.setBytes(2, bytes); // 2番目のplace holderへbyte[](バイナリーデータ)を設定 9statement.execute();

投稿2017/05/21 08:18

編集2017/05/28 16:16
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

conderdf

2017/05/28 11:18

ご回答ありがとうございます。 遅くなってしまい申し訳ございません。 ご指摘の点調べてみましたが、DBの値もエンコーディングした値となっていました。 [B@527a1b4b insertの処理が間違っていたと思い。現在調査しています。 なお、insertの処理は下記の通りです。 public void UpdateImgFile(){ //insert対象のJPEGファイル File file = new File("Flower.jpg"); ByteArrayOutputStream byteData =null; BufferedImage img = null; try { //BufferedImage型へ変換 img = ImageIO.read(file); //データがバイト配列に書き込まれる出力ストリームを実装 byteData= new ByteArrayOutputStream(); //ImageIOクラスでBufferedImageをバイト配列に変換         String format ="JPEG"; ImageIO.write(img,format,byteData); //byteDataの最終確認         //※ここでは [B@527a1b4bのような文字列となっていません System.out.print(byteData); } catch (IOException e) { // TODO 自動生成された catch ブロック e.printStackTrace(); } loginUserId="2"; //DB接続 if(jdbcTemplate==null){ DBconnect con =new DBconnect(); jdbcTemplate =new JdbcTemplate(con.dataSource()); } //SQL文の作成 String sql ="insert into imageTable(id,image,place) values('"+loginUserId+"',"+"'"; String sql2 ="',"+"'tokyo')"; //DB登録処理の実行 jdbcTemplate.update(sql+byteData.toByteArray()+sql2);      //byteData.toByteArray()とすると、[B@527a1b4bのような文字列となってしまいます。 } }
conderdf

2017/05/28 11:20

誤://ImageIOクラスでBufferedImageをバイト配列に変換 正://ImageIOクラスでBufferedImageをOutputStream に書き込み
KSwordOfHaste

2017/05/28 11:29 編集

少々迂遠に見えます。Flower.jpgをBufferedImageへ読み込む必要はありません。ファイルをそのままByteArrayOutputStreamへ書き込めばよいと思います。なお、"[B@..."になってしまうのはDBのカラムの型がまずいせいだと思います。カラムが文字列になっていませんか?BLOBにすべきと思います。
conderdf

2017/05/28 13:35

ファイルをそのままByteArrayOutputStreamにしてみましたがやはり、"[B@..."になってました。もう少し調べてみます。 カラムはBLOBでした。 BLOBのカラムについて調べていたら、「0x」で始まる16進文字列でINSERTを行うそうですね。 そのあたりも調べてみます。
KSwordOfHaste

2017/05/28 16:17

上のコードでbyte[]を文字列と連結してしまっていることに気づきました。それが本件の原因だと思いますので回答へ追記しました。
conderdf

2017/06/04 11:44

とても丁寧にご回答いただきありがとうございます。 ご指摘の通り、文字列とbyte[]を連結したことが原因でした。 spring frameworkでのinsertの方法を調べ、 下記のコードを通したところ、無事insertとselectしてBufferedImage型に変換することができました。 String sql ="insert into imageTable(id,image,place) values('"+loginUserId+"',"+'?'+",'tokyo')"; jdbcTemplate.update(sql,baos.toByteArray());
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問