事前準備
・フォームにテキストボックスとボタンを貼り付ける
・その下にPictureBoxを貼り付ける
・PictureBoxのBackColorプロパティをWhiteにする
テキストボックスの中に数字を1~15を入れ、
ボタンをクリックすることで、カラーパレットの
インデックスをセットします。
その後、マウスドラッグで描画します。
【ソースコード】
Imports System.Drawing.Imaging
Public Class Form1
Private Col(15) As Color
Private Palette As ColorPalette
Private ind As Integer = 0
Private mDownFlg As Boolean = False
Private stX As Integer, stY As Integer
Private enX As Integer, enY As Integer
Private Sub MakeColorPalette()
Col(0) = Color.Transparent
Col(1) = Color.Red
Col(2) = Color.Blue
Col(3) = Color.Green
Col(4) = Color.Yellow
Col(5) = Color.Aqua
Col(6) = Color.Purple
Col(7) = Color.Olive
Col(8) = Color.Pink
Col(9) = Color.Silver
Col(10) = Color.Gold
Col(11) = Color.SkyBlue
Col(12) = Color.Tomato
Col(13) = Color.Violet
Col(14) = Color.White
Col(15) = Color.Black
End Sub
Private bmp As Bitmap
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
MakeColorPalette()
bmp = New Bitmap(PictureBox1.Width, PictureBox1.Height, PixelFormat.Format4bppIndexed)
Palette = bmp.Palette
For i As Integer = 0 To 15
Palette.Entries(i) = Col(i)
Next
bmp.Palette = Palette
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Integer.TryParse(TextBox1.Text, ind)
End Sub
Private Sub mDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseDown
mDownFlg = True
stX = e.X : stY = e.Y
enX = e.X : enY = e.Y
End Sub
Private Sub mMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseMove
If mDownFlg = False Then Exit Sub
enX = e.X : enY = e.Y
Dim bmpDt As BitmapData = bmp.LockBits(New Rectangle(0, 0, PictureBox1.Width, PictureBox1.Height), ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed)
Dim ptr As IntPtr = bmpDt.Scan0
Dim bytes As Integer = bmpDt.Stride * PictureBox1.Height
Console.WriteLine(bmpDt.Stride)
Dim rgbvalues(bytes) As Byte
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbvalues, 0, bytes)
For i As Integer = Math.Min(stX, enX) To Math.Max(stX, enX)
For j As Integer = Math.Min(stY, enY) To Math.Min(stY, enY)
rgbvalues(CInt(i * bmpDt.Stride / PictureBox1.Width + j * bmpDt.Stride)) = CByte(ind)
Next
Next
System.Runtime.InteropServices.Marshal.Copy(rgbvalues, 0, ptr, bytes)
bmp.UnlockBits(bmpDt)
Dim g As Graphics
g = Graphics.FromHwnd(PictureBox1.Handle)
g.DrawImage(bmp, 0, 0)
g.Dispose()
stX = e.X : stY = e.Y
End Sub
Private Sub mUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles PictureBox1.MouseUp
mDownFlg = False
Dim g As Graphics = Graphics.FromHwnd(PictureBox1.Handle)
g.DrawImage(bmp, 0, 0)
g.Dispose()
End Sub
End Class
テキストボックスに0を入れると、透過色での描画になります。
4bppIndexedのBitmapですので、カラーパレットを作成し、
そのインデックスを、各ピクセルに割り当てていくことになります。
ここでは、テキストボックス内の数字が、カラーパレットの
インデックスになります。(ボタンをクリックする必要がありますが)
ただし、Graphics.Drawシリーズが使えないなど、
不便極まりないため、32bppArgb形式のBitmapなどを作成し、
それを8bpp(256色)や4bpp(16色)に変換した方が楽かもしれません。
関連記事
・Bitmap.LockBitsメソッド
・Byte配列
・Image.Palette
・画像を読み込み編集する1(LockBits)
システム開発のためのVB.NETプログラミング関係一覧に戻る