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

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

ただいまの
回答率

90.75%

  • C#

    6549questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • SQLite

    579questions

    SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

DBに画像を登録したい

受付中

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 674

yamaguti

score 99

お世話になります。

情報管理画面を作成しているのですが、画像登録ではまってしまっています。

128行目のパラメータの部分で
CS0029    型 'System.Drawing.Image' を 'System.Data.DbType' に暗黙的に変換できません    

上記のエラーが発生します。
画像やファイルを登録したことがなく、登録のしかたがいまいち理解できておりません。
ご教示のほどよろしくお願いいたします。

using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SQLite;

namespace 基幹システム.対人管理
{

    public partial class Taizintouroku : Form
    {
        public Taizintouroku()
        {
            InitializeComponent();

            #region 対人コードを自動付番
            DateTime CD = DateTime.Today.Date;

            System.Random r = new System.Random(1000);

            int i = r.Next(9);

            string ran = i.ToString();
            string Day = CD.ToString();
            string DayCD = Day.Substring(0, 10);

            string DayCD2 = DayCD.Replace('/',' ');

            //char[] removeChars = new Char[] { '\r', '\n' };

            //foreach(char c in removeChars)
            //{
            //    DayCD = DayCD.Replace(c.ToString(), "/");
            //}

            string KokyakuCd = ran + DayCD2;

            txttaizincd.Text = KokyakuCd;
            #endregion

            txttaizincd.Enabled = false;
        }

        public void button1_Click(object sender, EventArgs e)
        {
            //ダイアログを開く
            DialogResult dr = openFileDialog1.ShowDialog();

            pictureBox1.Image = Image.FromFile(openFileDialog1.FileName);
            //ファイルのアドレスを取得
            var pic = openFileDialog1.FileName;
            //バイト型に変更
            byte[] gazou = File.ReadAllBytes(pic);

            if (dr == DialogResult.OK)
            {
                //string filepass = dr.GetType.filepass;

            }
           // var a = picpic;
            //return a;
        }

        private void btntouroku_Click(object sender, EventArgs e)
        {

            string dbpath = Application.StartupPath + @"\kabukanri.db";
            using (SQLiteConnection con = new SQLiteConnection("Data Source=" + dbpath))
            {
                con.Open();
                DataTable datatable = new DataTable();

                using (SQLiteTransaction trans = con.BeginTransaction())
                {
                    //給料テーブルinsert用
                    StringBuilder sql = new StringBuilder();
                    SQLiteCommand cmd = con.CreateCommand();

                    #region 対人テーブル insert文 
                    sql.AppendLine("insert ");
                    sql.AppendLine("into 対人テーブル( ");
                    sql.AppendLine("  CD");
                    sql.AppendLine("  , 名前");
                    sql.AppendLine("  , 生年月日");
                    //sql.AppendLine("  , 年齢");
                    sql.AppendLine("  , 郵便番号");
                    sql.AppendLine("  , 住所");
                    sql.AppendLine("  , 顔写真");
                    sql.AppendLine("  , 性別");
                    sql.AppendLine("  , 備考");
                    sql.AppendLine("  , DEL_FLG");
                    sql.AppendLine(") ");
                    sql.AppendLine("values ( ");
                    sql.AppendLine("    @CD");
                    sql.AppendLine("  , @名前");
                    sql.AppendLine("  , @生年月日");
                    //sql.AppendLine("  , @年齢");
                    sql.AppendLine("  , @郵便番号");
                    sql.AppendLine("  , @住所");
                    sql.AppendLine("  , @顔写真");
                    sql.AppendLine("  , @性別");
                    sql.AppendLine("  , @備考");
                    sql.AppendLine("  , 0");
                    sql.AppendLine(")");

                    cmd.Parameters.Add("CD", System.Data.DbType.String);
                    cmd.Parameters.Add("名前", System.Data.DbType.String);
                    cmd.Parameters.Add("生年月日", System.Data.DbType.String);
                    cmd.Parameters.Add("年齢", System.Data.DbType.String);
                    cmd.Parameters.Add("郵便番号", System.Data.DbType.String);
                    cmd.Parameters.Add("住所", System.Data.DbType.String);
                    cmd.Parameters.Add("顔写真", System.Data.DbType.Binary);
                    cmd.Parameters.Add("性別", System.Data.DbType.String);
                    cmd.Parameters.Add("備考", System.Data.DbType.String);

                    cmd.Parameters["CD"].Value = txttaizincd.Text;
                    cmd.Parameters["名前"].Value = txtname.Text;
                    cmd.Parameters["生年月日"].Value = txtsenedate.Text;
                    //cmd.Parameters["年齢"].Value = txtage.Text;
                    cmd.Parameters["郵便番号"].Value = txtadd.Text;
                    cmd.Parameters["住所"].Value = txtzyusyo.Text;
                    cmd.Parameters["顔写真"].DbType =pictureBox1.Image;
                    if(radioButton1.Checked == true)
                    {
                        cmd.Parameters["性別"].Value = 1;
                    }
                    else if(radioButton2.Checked == true)
                    {
                        cmd.Parameters["性別"].Value = 2;
                    }
                    cmd.Parameters["備考"].Value = txtbiko.Text;

                    cmd.CommandText = sql.ToString();
                    cmd.ExecuteNonQuery();
                    trans.Commit();
                    MessageBox.Show("登録が完了しました。");
                    #endregion
                }
            }
        }

        private void txtage_Validating(object sender, CancelEventArgs e)
        {

        }
            #region 年齢を出すメソッド
        private static int GetAge(DateTime txtsenedate, DateTime today) {
            int age = today.Year - txtsenedate.Year;
            //誕生日がまだ来ていなければ、1引く
            if (today.Month < txtsenedate.Month ||
                (today.Month == txtsenedate.Month &&
                today.Day < txtsenedate.Day))
            {
                age--;
            }
            return age;
        }
        #endregion

        private void txtsenedate_Validated(object sender, EventArgs e)
        {
            #region 年齢を自動計算
            if (txtsenedate.TextLength < 10)
            {
               //seinenTip = new ToolTip(this.components);
                seinenTip.SetToolTip(txtsenedate,"生年月日はYYYY/MM/DD形式で入力してください");
                return;
            }

            string i = txtsenedate.Text;
            DateTime a = DateTime.Parse(i);

            DateTime birthDate = a;
            //現在の日付
            DateTime today = DateTime.Today;

            //年齢を計算する
            int age = GetAge(birthDate, today);

            int age2 = age;
            txtage.Text = age2.ToString();

        }
        #endregion
        private void txtsenedate_TextChanged(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/10/29 08:33 編集

    128行目と言われても行番号を振ってないと分からないのですが。(行番号を振ってほしいと言っているわけではありません。どの行かわかるようにしてほしいだけです)

    キャンセル

回答 2

0

System.Drawing.Imageはいわば画像イメージを表すクラスなので、SQLite3のBLOBの型と合致しません。例えば、対人テーブルの構成が以下のようになっていることを前提としますと、

CREATE TABLE 対人テーブル (
    CD TEXT
    名前 TEXT
    ....
    顔写真 BLOB
    ...
)


質問者様のコードでは以下のようにしているので、

cmd.Parameters.Add("顔写真", System.Data.DbType.Binary);


値としてはbyte[]型をセットします。顔写真の画像ファイルをSQLite3データベースに保存したいということだと思いますので、

cmd.Parameters["顔写真"].Value = new byte[]; // 顔写真の画像ファイルのバイト列


とのようになります。PictureBoxの画像イメージのバイト列を扱うには、以下のサイトの記事が参考になります。
バイト配列→画像オブジェクト/画像オブジェクト→バイト配列の変換を行うには?
こちらのコードを利用させていただくとして、DBの対人テーブルの顔写真カラムに保存(INSERT)するときは

ImageConverter conv = new ImageConverter();
data = (byte[])conv.ConvertTo(pictureBox1.Image, typeof(byte[]));
cmd.Parameters["顔写真"].Value = data;


反対に、SELECTでDBから取り出し、例えばPictureBoxにセットするときは

...
DataTable datatable = new DataTable();
SQLiteCommand cmd = con.CreateCommand();

cmd.CommandText = "SELECT CD, 名前, 顔写真 FROM 対人テーブル WHERE CD='1'";
var reader = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(reader);
if (dt.Rows.Count > 0)
{
    DataRow row = dt.Rows[0];

    // Debug.Assertで型が正しいか検証
    Debug.Assert(row.ItemArray[0] is string);
    string cd = (string)row.ItemArray[0];

    Debug.Assert(row.ItemArray[1] is string);
    string name = (string)row.ItemArray[1];

    // PictureBoxのImageにセット
    Debug.Assert(row.ItemArray[2] is byte[]);
    byte[] data = (byte[])row.ItemArray[2];

    ImageConverter conv = new ImageConverter();
    Image img = (Image)conv.ConvertFrom(data);
    pictureBox1.Image = img;

    Debug.WriteLine(string.Format("CD={0}, Name={1}", cd, name));
}
...


のようになるかと。当方ではVisual Studio 2017 + .NET Framework 4.6.1 の環境で確認しました。

蛇足ですが、PictureBoxのImageプロパティに新しいイメージをセットするときは、リソースリークを防ぐ為に適切にDispose()をするようご注意ください。上記の例ではそれはしていません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

cmd.Parameters["顔写真"].DbType =pictureBox1.Image;
この行を指していると思いますが

なぜこの行だけDbTypeに値を入れようとしているのでしょう?

また、button1_Click内でDBに入れるためにImageをByte配列にしているのだと思いますが、実際にDBへ登録する時にbyte[] gazouを使わずpictureBox1.Imageを使っているのはなぜでしょう?

DbParameter クラス(System.Data.SQLiteのヘルプではありませんが)
このあたりを参照してご自身が説明できれば、解決に至ると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C#

    6549questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • SQLite

    579questions

    SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。