SQL Server に OPENROWSET を使用して画像を登録し、登録された画像を ASP.NET で表示する

 

画像をデータベースに登録する方法と、FILESTREAMで登録する方法の両方をやってみる。

データベースに画像を登録する場合

画像をバイナリデータでデータベースに登録する。

登録する画像(F:\TEMP\dark_knight_rises_ver9_xlg.jpg)
dark_knight_rises_ver9_xlg

 

テーブルを作る

テーブル「IMAGE」作成
CREATE TABLE [dbo].[IMAGE](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [IMAGE] [varbinary](max) NULL,
CONSTRAINT [PK_IMAGE] PRIMARY KEY CLUSTERED
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

 

テーブルに画像を登録する

画像データをインポート
INSERT INTO [TEST].[dbo].[IMAGE]
SELECT [IMAGEDATA].* FROM
OPENROWSET(BULK 'F:\TEMP\dark_knight_rises_ver9_xlg.jpg', SINGLE_BLOB) AS [IMAGEDATA]

 

バイナリで画像がテーブルに登録された。
01

 

ASP.NET でバイナリを読み込んで画像を表示

完成イメージ

02030405

image.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="image.aspx.vb" Inherits="image" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        ID<asp:TextBox ID="TextBoxID" runat="server" Columns="5"></asp:TextBox>
        W<asp:TextBox ID="TextBoxW" runat="server" Columns="4" MaxLength="4"></asp:TextBox>
        H<asp:TextBox ID="TextBoxH" runat="server" Columns="4" MaxLength="4"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="" />
        <br />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TESTConnectionString %>" SelectCommand="SELECT [IMAGE] FROM [IMAGE] WHERE ([ID] = @ID)">
            <SelectParameters>
                <asp:ControlParameter ControlID="TextBoxID" Name="ID" PropertyName="Text" Type="Int32" />
            </SelectParameters>
        </asp:SqlDataSource>
    
    </div>
    </form>
</body>
</html>
image.aspx.vb
Partial Class image
    Inherits System.Web.UI.Page

    Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim dv As Data.DataView = SqlDataSource1.Select(DataSourceSelectArguments.Empty)
        If Not dv Is Nothing Then
            If dv.Table.Rows.Count > 0 Then
                If Not IsDBNull(dv.Table.Rows(0)(0)) Then
                    Dim oW As Integer = TextBoxW.Text
                    Dim oH As Integer = TextBoxH.Text
                    Dim bmp As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(New System.IO.MemoryStream(DirectCast(dv.Table.Rows(0)(0), Byte())))
                    If bmp.Width > oW Or bmp.Height > oH Then
                        Dim s As Double = Math.Min(oW / bmp.Width, oH / bmp.Height)
                        Dim sW As Integer = CInt(s * bmp.Width)
                        Dim sH As Integer = CInt(s * bmp.Height)
                        Dim outBmp As System.Drawing.Bitmap = New System.Drawing.Bitmap(sW, sH)
                        Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(outBmp)
                            g.DrawImage(bmp, 0, 0, sW, sH)
                        End Using
                        outBmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                    Else
                        Response.BinaryWrite(DirectCast(dv.Table.Rows(0)(0), Byte()))
                    End If
                    Response.End()
                End If
            End If
        End If

    End Sub
End Class

 

 

FILESTREAMで画像を登録する場合

登録する画像(F:\temp\cowboys_and_aliens_xlg.jpg)
cowboys_and_aliens_xlg

テーブル作成(FILESTREAM)

08

テーブル「IMAGEFS」作成
CREATE TABLE [dbo].[IMAGEFS](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [STREAMID] [uniqueidentifier] ROWGUIDCOL  NOT NULL,
    [IMAGE] [varbinary](max) FILESTREAM  NULL,
CONSTRAINT [PK_IMAGEFS] PRIMARY KEY CLUSTERED
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] FILESTREAM_ON [FileStreamGroup1],
UNIQUE NONCLUSTERED
(
    [STREAMID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] FILESTREAM_ON [FileStreamGroup1]

 

FILESTREAMで画像を登録

画像データをインポート
INSERT INTO [TEST].[dbo].[IMAGEFS]
SELECT NEWID(),[IMAGEDATA].* FROM
OPENROWSET(BULK 'F:\TEMP\cowboys_and_aliens_xlg.jpg', SINGLE_BLOB) AS [IMAGEDATA]

 

FILESTREAMで画像が登録された。
09

 

ASP.NET でバイナリを読み込んで画像を表示

※データ読み出しのテーブルが違うだけで、データベースに画像を登録した場合と同じ。FILESTREAM か データベースに登録か?で処理に変更はない。

0607

imageFS.aspx
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="imageFS.aspx.vb" Inherits="imageFS" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
        ID<asp:TextBox ID="TextBoxID" runat="server" Columns="5"></asp:TextBox>
        W<asp:TextBox ID="TextBoxW" runat="server" Columns="4" MaxLength="4"></asp:TextBox>
        H<asp:TextBox ID="TextBoxH" runat="server" Columns="4" MaxLength="4"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="" />
        <br />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TESTConnectionString %>" SelectCommand="SELECT [IMAGE] FROM [IMAGEFS] WHERE ([ID] = @ID)">
            <SelectParameters>
                <asp:ControlParameter ControlID="TextBoxID" Name="ID" PropertyName="Text" Type="Int32" />
            </SelectParameters>
        </asp:SqlDataSource>
    
    </div>
    </form>
</body>
</html>
imageFS.aspx.vb
Partial Class imageFS
    Inherits System.Web.UI.Page

    Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

        Dim dv As Data.DataView = SqlDataSource1.Select(DataSourceSelectArguments.Empty)
        If Not dv Is Nothing Then
            If dv.Table.Rows.Count > 0 Then
                If Not IsDBNull(dv.Table.Rows(0)(0)) Then
                    Dim oW As Integer = TextBoxW.Text
                    Dim oH As Integer = TextBoxH.Text
                    Dim bmp As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(New System.IO.MemoryStream(DirectCast(dv.Table.Rows(0)(0), Byte())))
                    If bmp.Width > oW Or bmp.Height > oH Then
                        Dim s As Double = Math.Min(oW / bmp.Width, oH / bmp.Height)
                        Dim sW As Integer = CInt(s * bmp.Width)
                        Dim sH As Integer = CInt(s * bmp.Height)
                        Dim outBmp As System.Drawing.Bitmap = New System.Drawing.Bitmap(sW, sH)
                        Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(outBmp)
                            g.DrawImage(bmp, 0, 0, sW, sH)
                        End Using
                        outBmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                    Else
                        Response.BinaryWrite(DirectCast(dv.Table.Rows(0)(0), Byte()))
                    End If
                    Response.End()
                End If
            End If
        End If

    End Sub

End Class

 

バイナリで保存されている画像を縦横比を固定して表示する方法として参考にさせていただいたページ

プログラムのメモ置き場 @ ウィキ – ASP.NET/asp007
http://www21.atwiki.jp/chaka-poko/pages/33.html

ありがとうございました。

コメント

このブログの人気の投稿

ダブルクォーテーションで括られたCSVカ​ンマ区切りテキストファイルを SQL Server で Bulk Insert する方法

PowerShellでTSV/CSVの列を絞り込んで抽出し、(先頭/行末)からN行出力する

IKEAの鏡を壁に取り付ける