C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: Oracleから取得した画像ファイルの表示について


(過去ログ 55 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■30893 / inTopicNo.1)  Oracleから取得した画像ファイルの表示について
  
□投稿者/ ひでき (1回)-(2009/01/08(Thu) 17:24:55)

分類:[C#] 

お世話になります。
C#にて、Oracleから取得した
画像データの表示について
ご教授頂きたく投稿させて頂きました。
よろしくお願い致します。

■やりたい事
Oracleに格納しているデータの画像ファイル
(元ファイルはjpg、テーブル列の型は「LONG RAW」)を
画面のPictureBoxに表示したい。

こちらのサンプル等も参考にさせて頂き
下記ソースを組み込みましたが

private void button2_Click(object sender, EventArgs e)
{
    try
    {
        OracleConnection connection = new OracleConnection("Data Source=XXX;User ID=XXX;Password=XXX;");
        OracleDataAdapter adapter = new OracleDataAdapter("SELECT * FROM XXX WHERE XXX_CODE = '123'", connection);
        DataTable table = new DataTable();
        adapter.Fill(table);
        DataRow row = table.Rows[0];
        OracleBinary binaly = new OracleBinary((byte[])row["PIC"]);

        this.picture.Image = this.ConvBinaryToImage(binaly.Value);
    }
    catch (Exception exp)
    {
        MessageBox.Show(exp.ToString());
    }
}

private Image ConvBinaryToImage (byte[] data)
{
    Image img = null;
    MemoryStream stream = new System.IO.MemoryStream(data);
    img = Image.FromStream(stream); // 例外発生:使用されたパラメータが有効ではありません

    return img;
}

メソッド内の
「img = Image.FromStream(stream); 」
にて例外が発生してしまい
原因及び対処方法がわかりかねています。

LOCALの画像ファイルを読み込んで設定する処理は
同じような方法で表示できたのですが
バイナリファイルの対処がわかりません。

恐れ入りますが、ご教授の程お願い申し上げます。

開発環境ですが
OS:WinXP SP2 
言語:C#(VS.NET2008、.Net Framework2.0使用)
DB:Oracle 9.2.0.1.0
になります。

以上、よろしくお願いします。

引用返信 編集キー/
■30901 / inTopicNo.2)  Re[1]: Oracleから取得した画像ファイルの表示について
□投稿者/ やじゅ (905回)-(2009/01/08(Thu) 18:42:38)
やじゅ さんの Web サイト
No30893 (ひでき さん) に返信
> LOCALの画像ファイルを読み込んで設定する処理は
> 同じような方法で表示できたのですが
> バイナリファイルの対処がわかりません。
>

見たところは、悪くなさそうなんですよね。
そうするとOracleから読み出されたデータが悪いのかな。

LOCALの画像ファイルを読み込んだstreamのデータと
Oracleから読み込んだstreamのデータを比較してみるとか

テスト用のデータは小さく簡易(真っ白なデータとか)な画像ファイルでやってみるといいかな。
引用返信 編集キー/
■30904 / inTopicNo.3)  Re[1]: Oracleから取得した画像ファイルの表示について
□投稿者/ はつね (919回)-(2009/01/08(Thu) 19:01:41)
はつね さんの Web サイト
No30893 (ひでき さん) に返信
> OracleBinary binaly = new OracleBinary((byte[])row["PIC"]);

DataTableに一度入れてしまうのではなくバイナリデータはOracleDataReaderなどで個別に取り出して、
OracleDataReaderのGetOracleBinaryの値をOracleBinaryの変数(この場合、binary)に入れてから、

> this.picture.Image = this.ConvBinaryToImage(binaly.Value);

を実行してみたら如何でしょうか。

引用返信 編集キー/
■30905 / inTopicNo.4)  Re[2]: Oracleから取得した画像ファイルの表示について
□投稿者/ ひでき (2回)-(2009/01/08(Thu) 19:05:38)
No30901 (やじゅ さん) に返信
>
> 見たところは、悪くなさそうなんですよね。
> そうするとOracleから読み出されたデータが悪いのかな。
>
> LOCALの画像ファイルを読み込んだstreamのデータと
> Oracleから読み込んだstreamのデータを比較してみるとか
>
> テスト用のデータは小さく簡易(真っ白なデータとか)な画像ファイルでやってみるといいかな。

返信ありがとうございます。

> そうするとOracleから読み出されたデータが悪いのかな。
Oracleには直接挿入する方法がわからなかったため(これもまずいと思いますが)
Accessからリンクを張り
メニューの「挿入」→「オブジェクト」
から画像ファイルを選択し、登録を行いました。。

Oracle専用に登録する手段があるならば
そちらの方が良いとは思うのですが実行できていません;

ちなみに、画像ファイルはLOCALも
Oracleに登録したのも同じファイルを使用しました。

また、ご教授頂ければ幸いです。
よろしくお願い致します。
引用返信 編集キー/
■30909 / inTopicNo.5)  Re[2]: Oracleから取得した画像ファイルの表示について
□投稿者/ ひでき (3回)-(2009/01/08(Thu) 19:13:28)
No30904 (はつね さん) に返信
>>        OracleBinary binaly = new OracleBinary((byte[])row["PIC"]);
> 
> DataTableに一度入れてしまうのではなくバイナリデータはOracleDataReaderなどで個別に取り出して、
> OracleDataReaderのGetOracleBinaryの値をOracleBinaryの変数(この場合、binary)に入れてから、
> 
>>        this.picture.Image = this.ConvBinaryToImage(binaly.Value);
> 
> を実行してみたら如何でしょうか。
> 

返信ありがとうございます。

実はGetOracleBinaryを使う方法も試したのですが
↓
private void button2_Click(object sender, EventArgs e)
{
    try
    {
        OracleConnection connection = new OracleConnection("("Data Source=XXX;User ID=XXX;Password=XXX;");
        OracleCommand cmd = new OracleCommand("SELECT * FROM XXX WHERE XXX_CODE = '123'", connection);
        connection.Open();
        OracleDataReader reader = cmd.ExecuteReader();
        if (reader.Read())
        {
            OracleBinary binary = reader.GetOracleBinary(1);
            this.facePicture.Image = this.ConvBinaryToImage(binary.Value);
        }

    }
    catch (Exception exp)
    {
        MessageBox.Show(exp.ToString());
    }
}

private Image ConvBinaryToImage (byte[] data)
{
    Image img = null;
    MemoryStream stream = new System.IO.MemoryStream(data);
    img = Image.FromStream(stream); // 例外発生:使用されたパラメータが有効ではありません

    return img;
}

最初の投稿と同じように
img = Image.FromStream(stream); にて、例外が発生してしまいました。
正直、どちらも方法もふさがってしまったので手詰まった状態です。

何か問題点等ございましたら
ご指導頂きたくお願い申し上げます。

よろしくお願い致します。

引用返信 編集キー/
■30915 / inTopicNo.6)  Re[3]: Oracleから取得した画像ファイルの表示について
□投稿者/ 魔界の仮面弁士 (956回)-(2009/01/08(Thu) 21:18:09)
2009/01/08(Thu) 21:35:30 編集(投稿者)
No30905 (ひでき さん) に返信
> OracleConnection connection = new OracleConnection("Data Source=XXX;User ID=XXX;Password=XXX;");
Using / Close は?

> 画面のPictureBoxに表示したい。
Long Raw に、生のバイナリがそのまま格納されているのであれば、
最初の No30893 のコードで、問題無く表示できますよ。


> Accessからリンクを張り
> メニューの「挿入」→「オブジェクト」
> から画像ファイルを選択し、登録を行いました。。
それはつまり、ODBCリンクテーブルに対しての操作ですよね。
Access VBA のアプリならば良いですが、C# アプリで使うのであれば、
その登録方法は避けてください。

Access の[挿入]メニューからの場合、ファイルの生バイナリが挿入されるわけでは無く、
OLE (パッケージャ)オブジェクトとしてのデータ挿入が行われる事になります。
http://support.microsoft.com/kb/884484/ja

このため、データ内に OLE ヘッダ情報が付加されてしまう結果となり、
元ファイルのバイナリとは一致しなくなってしまいます。

データ内容から、元データを予想して取り出す方法もありますが、
そもそもは、ファイルの生バイナリを登録しておくべきでしょう。
http://support.microsoft.com/kb/175261/ja


たとえば、Oracle 上に
 CREATE TABLE XXX (XXX_CODE CHAR(3) PRIMARY KEY, PIC LONG RAW)
なテーブルを用意してあるのだとします。


C# から登録するのであれば、たとえばこんな感じ。

string sql = "INSERT INTO XXX (XXX_CODE, PIC) VALUES (:ID, :IMG)";
using (OracleCommand cmd = new OracleCommand(sql, connection))
{
    OracleParameter ID = cmd.Parameters.Add("ID", OracleType.Char, 3);
    OracleParameter IMG = cmd.Parameters.Add("IMG", OracleType.LongRaw);

    ID.Value = "123";
    IMG.Value = File.ReadAllBytes(@"C:\a.bmp");

    connection.Open();
    cmd.ExecuteNonQuery();
    connection.Close();
}


■No30905 (ひでき さん) に返信
> Oracle専用に登録する手段があるならば
> そちらの方が良いとは思うのですが実行できていません;
生のバイナリを Oracle に登録するための画面は、Access 側には用意されていないので、
SQL で直接指定するか、Access VBA から AppendChunk メソッドを呼び出さねばなりません。


VBA のコードは書いても仕方ないので、SQL の記述例を書いておきます。
(下記では、画像のバイナリデータを 16進数にて指定しています)

****** ODBC リンクテーブルの場合 ******

INSERT INTO リンクテーブル名 (XXX_CODE, PIC) VALUES (
  '123', 
  0x424D860000000000000076000000280000000400000004000000010004000000000010000000C40E0000C40E000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AECD000026450000F89B000007130000
)

****** パススルー クエリの場合 ******

INSERT INTO XXX (XXX_CODE, PIC) VALUES (
  '123', 
  HEXTORAW('424D860000000000000076000000280000000400000004000000010004000000000010000000C40E0000C40E000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AECD000026450000F89B000007130000')
)

引用返信 編集キー/
■31006 / inTopicNo.7)  Re[4]: Oracleから取得した画像ファイルの表示について
□投稿者/ ひでき (4回)-(2009/01/13(Tue) 11:07:04)
No30915 (魔界の仮面弁士 さん) に返信
> 2009/01/08(Thu) 21:35:30 編集(投稿者)
>
> ■No30905 (ひでき さん) に返信
>>OracleConnection connection = new OracleConnection("Data Source=XXX;User ID=XXX;Password=XXX;");
> Using / Close は?
>
>>画面のPictureBoxに表示したい。
> Long Raw に、生のバイナリがそのまま格納されているのであれば、
> 最初の No30893 のコードで、問題無く表示できますよ。
>
>
>>Accessからリンクを張り
>>メニューの「挿入」→「オブジェクト」
>>から画像ファイルを選択し、登録を行いました。。
> それはつまり、ODBCリンクテーブルに対しての操作ですよね。
> Access VBA のアプリならば良いですが、C# アプリで使うのであれば、
> その登録方法は避けてください。
>
> Access の[挿入]メニューからの場合、ファイルの生バイナリが挿入されるわけでは無く、
> OLE (パッケージャ)オブジェクトとしてのデータ挿入が行われる事になります。
> http://support.microsoft.com/kb/884484/ja
>
> このため、データ内に OLE ヘッダ情報が付加されてしまう結果となり、
> 元ファイルのバイナリとは一致しなくなってしまいます。
>
> データ内容から、元データを予想して取り出す方法もありますが、
> そもそもは、ファイルの生バイナリを登録しておくべきでしょう。
> http://support.microsoft.com/kb/175261/ja
>
>
> たとえば、Oracle 上に
>  CREATE TABLE XXX (XXX_CODE CHAR(3) PRIMARY KEY, PIC LONG RAW)
> なテーブルを用意してあるのだとします。
>
>
> C# から登録するのであれば、たとえばこんな感じ。
>
> string sql = "INSERT INTO XXX (XXX_CODE, PIC) VALUES (:ID, :IMG)";
> using (OracleCommand cmd = new OracleCommand(sql, connection))
> {
> OracleParameter ID = cmd.Parameters.Add("ID", OracleType.Char, 3);
> OracleParameter IMG = cmd.Parameters.Add("IMG", OracleType.LongRaw);
>
> ID.Value = "123";
> IMG.Value = File.ReadAllBytes(@"C:\a.bmp");
>
> connection.Open();
> cmd.ExecuteNonQuery();
> connection.Close();
> }
>
>
> ■No30905 (ひでき さん) に返信
>>Oracle専用に登録する手段があるならば
>>そちらの方が良いとは思うのですが実行できていません;
> 生のバイナリを Oracle に登録するための画面は、Access 側には用意されていないので、
> SQL で直接指定するか、Access VBA から AppendChunk メソッドを呼び出さねばなりません。
>
>
> VBA のコードは書いても仕方ないので、SQL の記述例を書いておきます。
> (下記では、画像のバイナリデータを 16進数にて指定しています)
>
> ****** ODBC リンクテーブルの場合 ******
>
> INSERT INTO リンクテーブル名 (XXX_CODE, PIC) VALUES (
> '123',
> 0x424D860000000000000076000000280000000400000004000000010004000000000010000000C40E0000C40E000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AECD000026450000F89B000007130000
> )
>
> ****** パススルー クエリの場合 ******
>
> INSERT INTO XXX (XXX_CODE, PIC) VALUES (
> '123',
> HEXTORAW('424D860000000000000076000000280000000400000004000000010004000000000010000000C40E0000C40E000000000000000000000000000000008000008000000080800080000000800080008080000080808000C0C0C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF00AECD000026450000F89B000007130000')
> )

返信ありがとうございます。



教えて頂いたやり方にて、
> string sql = "INSERT INTO XXX (XXX_CODE, PIC) VALUES (:ID, :IMG)";
> using (OracleCommand cmd = new OracleCommand(sql, connection))
> {
> OracleParameter ID = cmd.Parameters.Add("ID", OracleType.Char, 3);
> OracleParameter IMG = cmd.Parameters.Add("IMG", OracleType.LongRaw);
>
> ID.Value = "123";
> IMG.Value = File.ReadAllBytes(@"C:\a.bmp");
>
> connection.Open();
> cmd.ExecuteNonQuery();
> connection.Close();
> }
画像を登録し読み込みを行ったらところ
画像表示ができました!
本当にありがとうございます。

画像登録についてはこのような方法で
バイナリを登録するんですね。
大変勉強になりました。

本当ありがとうございました。
今後ともよろしくお願い致します。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -