- PR -

透過gifの切り抜きについて

1
投稿者投稿内容
Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-05-22 11:02
お世話になります。
透過Gifを部分的に切り抜きたいのですが
透過色が上手く指定できずに困っています。
以下がソースです。

Dim bmpLoadImage as Bitmap
Dim fixImage As Bitmap
Dim TransparentColor As Color
Dim dc1 As IntPtr
Dim dc2 As IntPtr
Dim memg As Graphics
Dim hbmp As IntPtr

bmpLoadImage = New Bitmap(strFname)

Palette = bmpLoadImage.Palette
For i As Int32 = 0 To Palette.Entries.Length - 1
If Palette.Entries(i).A = 0 Then
TransparentColor = Palette.Entries(i)
Exit For
End If
Next

dc1 = CreateCompatibleDC(Graphics.FromHwnd(Picturebox1.Handle).GetHdc)
hbmp = SelectObject(dc1, bmpLoadImage.GetHbitmap)

fixImage = New Bitmap(intIconWidth, intIconHeight, Graphics.FromHwnd(Picturebox1.Handle))

memg = Graphics.FromImage(fixImage)

dc2 = memg.GetHdc()

TransparentBlt(dc2, _
0, _
0, _
mpFrame1.Width - mpFrame1.LineWidth * 2, _
mpFrame1.Height - mpFrame1.LineWidth * 2, _
dc1, _
mpFrame1.Left + mpFrame1.LineWidth, _
mpFrame1.Top + mpFrame1.LineWidth, _
mpFrame1.Width - mpFrame1.LineWidth * 2, _
mpFrame1.Height - mpFrame1.LineWidth * 2, _
RGB(TransparentColor.R, TransparentColor.G, TransparentColor.B))
)


TransparentBltで透過色を固定でRGB(211, 211, 211)とすると上手くいきます。
因みに、RGB値はどの透過色を用いた透過GifでもRGB(211, 211, 211)を
使用すると上手くいきます。

どうやら
CreateCompatibleDC
SelectObject
で透過色がこわれてしまっている
もしくは透過はされていてデフォルトの背景色で
塗りつぶされているようなのですが
どの用にしてこれを回避したらよいのでしょうか?

よろしくお願いします。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-05-22 11:50
引用:

どの用にしてこれを回避したらよいのでしょうか?



「透過色」の概念をほとんど持っていない Windows API なんか使わないで、Graphics.DrawImage() 等々を使えばいいんじゃないでしょうか。
Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-05-22 13:00
早速のご回答ありがとうございます。

Graphics.DrawImageを使用した方法も考えたのですが、

Dim g as Graphics = Graphics.FromImage(bmpLoadImage)
とやると
『インデックス付きのピクセル形式をもつイメージからグラフィックスオブジェクトを作成することはできません。』
という実行時エラーが出てしまいます。
これはGifがカラーパレットを使用しているためだと思われます。

また、上記コード前に
bmpLoadImage.PixelFormat = Imaging.PixelFormat.Format32bppArgb
を書いてみたのですが、
『プロパティ'PixelFormat'は'ReadOnly'です。』
とおこられてしまいます。

なにかよい方法をご教授下さい。よろしくお願いします。
rvmx
大ベテラン
会議室デビュー日: 2002/09/26
投稿数: 184
お住まい・勤務地: 愛媛県
投稿日時: 2007-05-22 14:01
今日は

インデツクス付きのイメージでGraphicsを使う時は
一度からのnew Bitmap(w,h)でイメージを作り、それにDrawImageで描けば32bit化できます。
Graphicsはそのまま使うか、再度Graphics.FromImageで取得すれば良いと思います。
Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-05-22 14:58
貴重なご回答ありがとうございます。
rvmxさんのご回答の通りに組みなおしたところエラーなく動作しました。
以下ソースです。

Picturebox1.Image = New Bitmap(bmpLoadImage.Width, bmpLoadImage.Height)

Dim ulCorner1 As New Point(0, 0)
Dim urCorner1 As New Point(mpFrame1.Width - mpFrame1.LineWidth * 2, 0)
Dim llCorner1 As New Point(0, mpFrame1.Height - mpFrame1.LineWidth * 2)
Dim destPara1 As Point() = {ulCorner1, urCorner1, llCorner1}
Dim srcRect As New Rectangle(mpFrame1.Left + mpFrame1.LineWidth, _
mpFrame1.Top + mpFrame1.LineWidth, _
mpFrame1.Width - mpFrame1.LineWidth * 2, _
mpFrame1.Height - mpFrame1.LineWidth * 2)
Dim units As GraphicsUnit = GraphicsUnit.Pixel
Dim imgAttr As New System.Drawing.Imaging.ImageAttributes

imgAttr.SetColorKey(TransparentColor, TransparentColor, Imaging.ColorAdjustType.Bitmap)

g = Graphics.FromImage(Picturebox1.Image)

g.DrawImage(Image.FromHbitmap(bmpLoadImage.GetHbitmap), destPara1, srcRect, units)

fixImage = Picturebox1.Image
中略
bmpLoadImage = New Bitmap(fixImage, sz)
表示処理

しかしながら
この方法でも透過色が(r,g,b)=(211,211,211)と化けてしまいます。

固定で
TransparentColor = Color.FromArgb(255, 211, 211, 211)
とすると思い通りの動作します。
何か処理が足りないのでしょうか?
それとも、根本的になにか問題があるのでしょうか...

よろしくお願いします。

Hidering
常連さん
会議室デビュー日: 2007/05/22
投稿数: 33
投稿日時: 2007-05-27 15:29
解決しました。

g.DrawImage(Image.FromHbitmap(bmpLoadImage.GetHbitmap), destPara1, srcRect, units)

g.DrawImage(bmpLoadImage, destPara1, srcRect, units, imgAttr)
と書き直したら上手くいきました。

rvmxさん、渋木宏明(ひどり)さん親切にありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)