SQL Server にバイナリで保存されている画像データをASP.NETで半透明にして背景として表示する


こういう風にしたい

映画の背景画像の上にある文字やポスター画像は透明化されず、背景画像だけを透明化(20%)したい。
01

こうなってしまう

背景を透明化(50%)すると、その上の文字やボタンまで透明化されてしまう。
11

透明化しないとこういう感じ

文字が見えにくい。
10


どう実現するか?

明るい背景なら黒系、暗い背景なら白系の文字色に動的に変更すればいいのかもしれないが、画像の明るさを自動判定する能力を私は持ち合わせていないので、画像を透明化して、文字を目立たせるように考えた。

前提として、背景画像はこうやって表示している


試行錯誤

  • Panel に CSS で opacity: 0.5 と指定すると、Panel 内にある FormView まで透明化されてしまう。
    11
  • Panel の中にさらに Panel を設置して、内側の Panel に FormView を置いても、透明化されてしまう。FormView の CSS で opacity: 1.0 としても透明化は解除されない。
  • バイナリデータを画像化するページ(GetImageAlpha.aspx)の imgタグ、Bodyタグに CSS で opacity: 0.5等の透明化を試みるが全くダメ。そもそもResponse.OutputStream で画像をページに書き出しているので、CSS の適用の余地がなかった。

とりあえずできた

CSS で背景だけを透明化できないので、バイナリデータを画像としてページに書き出す際に透明化できないか?縦横比を維持して自在に画像表示できるのだから、透明化だってできるでしょ?グーグル先生に導かれて・・・・
透明化については下記を参考にさせていただきました。ありがとうございました。
画像を半透明で表示する: .NET Tips: C#, VB.NET
http://dobon.net/vb/dotnet/graphics/hadeinimage.html
cm.MatrixNN の NN の値を小さくするとより透明(暗く)に、大きくすると明るくなる。この数値の意味や透明化の仕組みはよくわからない。詳しくは参考にしたページに書かれている。
※ソースコードは日本語表記の部分が欠けてます。
GetImageAlpha.aspx.vb
Imports System.Drawing
Partial Class GetImageAlpha
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        'ColorMatrix
        Dim cm As New System.Drawing.Imaging.ColorMatrix()
        'ColorMatrix0.5
        'cm.Matrix00 = 0.3
        'cm.Matrix11 = 0.3
        'cm.Matrix22 = 0.3
        'cm.Matrix33 = 0.3
        'cm.Matrix44 = 0.3
        cm.Matrix00 = Request.QueryString("Matrix00")
        cm.Matrix11 = Request.QueryString("Matrix11")
        cm.Matrix22 = Request.QueryString("Matrix22")
        cm.Matrix33 = Request.QueryString("Matrix33")
        cm.Matrix44 = Request.QueryString("Matrix44")

        'ImageAttributes
        Dim ia As New System.Drawing.Imaging.ImageAttributes()
        'ColorMatrix
        ia.SetColorMatrix(cm)

        Dim dv As Data.DataView = SDS.Select(DataSourceSelectArguments.Empty)
        Dim Width As Integer = Request.QueryString("Width")
        Dim Height As Integer = Request.QueryString("Height")

        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 = Width '
                    Dim oH As Integer = Height '
                    Dim bmp As System.Drawing.Bitmap = System.Drawing.Bitmap.FromStream(New System.IO.MemoryStream(DirectCast(dv.Table.Rows(0)(0), Byte())))
                    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, New Rectangle(0, 0, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, ia)
                    End Using
                    outBmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg)
                    Response.End()
                End If
            End If
        End If

    End Sub

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

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server" class="AlphaBackGround">
        <asp:SqlDataSource ID="SDS" runat="server"
            ConnectionString="<%$ ConnectionStrings:MOVIEConnectionString %>"
            SelectCommand="getImage" SelectCommandType="StoredProcedure">
            <SelectParameters>
                <asp:QueryStringParameter DefaultValue="" Name="ID" QueryStringField="ID" Type="Decimal" />
                <asp:QueryStringParameter DefaultValue="" Name="MODE" QueryStringField="MODE" Type="String" />
            </SelectParameters>
        </asp:SqlDataSource>
    </form>
</body>
</html>
getImageAlphaを呼び出し、PanelMainの背景に透明化された映画のアートを表示する。
DetaiForm8.aspx.vbの一部
Dim objIDLabel As Object = FormViewDetail.FindControl("IDLabel")
If Not objIDLabel Is Nothing Then
    PanelMain.BackImageUrl = "GetImageAlpha.aspx?ID=" + objIDLabel.text + "&MODE=&Width=1920&Height=1080" + "&Matrix00=" + Global.ASP.global_asax.Matrix00 _
                                                                                                                            + "&Matrix11=" + Global.ASP.global_asax.Matrix11 _
                                                                                                                            + "&Matrix22=" + Global.ASP.global_asax.Matrix22 _
                                                                                                                            + "&Matrix33=" + Global.ASP.global_asax.Matrix33 _
                                                                                                                            + "&Matrix44=" + Global.ASP.global_asax.Matrix44
End If
バイナリで登録されている画像データを取得するストアドプロシージャ。
※このソースも日本語が欠けてます。
getImage
CREATE PROCEDURE [dbo].[getImage]
     @ID            int
    ,@MODE            NVARCHAR(50)
AS
BEGIN
    SET NOCOUNT ON;
    IF @MODE = ''
        BEGIN
            SELECT []
            FROM dbo.
            WHERE (ID = @ID)
        END

    IF @MODE = ''
        BEGIN
            SELECT []
            FROM dbo.
            WHERE (ID = @ID)
        END

    IF @MODE = 'IMDbPoster'
        BEGIN
            SELECT B.PosterFullImage
            FROM dbo. as A
                LEFT JOIN [dbo].[TMDbIMDb] as B on A.TMDbID = B.TMDbID
            WHERE (ID = @ID)
        END

    IF @MODE = 'TMDbCast'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbCast]
            WHERE (CastID = @ID)
        END
   
        IF @MODE = 'TMDbCrew'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbCrew]
            WHERE (CrewID = @ID)
        END

    IF @MODE = 'TMDbPoster'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbPoster]
            WHERE (ID = @ID)
        END

    IF @MODE = 'TMDbBackDrop'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbBackDrop]
            WHERE (ID = @ID)
        END

    IF @MODE = 'TMDbPerson'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbPerson]
            WHERE (PersonID = @ID)
        END

    IF @MODE = 'TMDbPersonImage'
        BEGIN
            SELECT [Image]
            FROM [dbo].[TMDbPersonImage]
            WHERE (ID = @ID)
        END

    IF @MODE = 'TMDbPersonMovie'
        BEGIN
            SELECT []
            FROM [dbo].[]
            WHERE (ID = @ID)
        END

END

完成形

見栄えが良くなったと思う。
(変更前)
20

(変更後)透明度を30%にしてみた。罫線を削除してタイトル文字を大きくした。
22
こちはら詳細画面を表示したところ。
2324

以下は透明度20%。20%、30%どちらにするかは後ほど考える。
01
上記画面で、TMDbInformation ボタンをクリックすると、Ajax Control Toolkit の ModalPopup で 詳細画面が表示されるけど、こちらもこれまでどおり、背景が透明化されている。
02
下記は好きな作品。
0304

コメント

このブログの人気の投稿

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

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

IKEAの鏡を壁に取り付ける