Private Function Mosaic(sourceImage As Image, mosaicSize As Integer) As Image '▼色情報の取得 'sourceImageの画像の色情報を配列 rgbBits にコピーします。 Dim bmp As Bitmap = CType(sourceImage.Clone, Bitmap) Dim bmpData As Imaging.BitmapData = bmp.LockBits( New Rectangle(0, 0, bmp.Width, bmp.Height), Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat) Dim bitCount As Integer = Math.Abs(bmpData.Stride) * bmp.Height Dim rgbBits(bitCount - 1) As Byte 'rgbBitsは 赤・青・緑の情報を持つので、画像のピクセル数 × 3 の数の長さになります。 System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, rgbBits, 0, bitCount) '縦・横いくつのモザイクに分割されるか計算します。 Dim mosaicCountX As Integer = CInt(Math.Ceiling(bmp.Width / mosaicSize)) Dim mosaicCountY As Integer = CInt(Math.Ceiling(bmp.Height / mosaicSize)) '▼モザイクごとに色を設定 For mosaicIndexY = 0 To mosaicCountY - 1 For mosaicIndexX = 0 To mosaicCountX - 1 '現在のモザイクの画像上の座標 Dim pointLeft As Integer = mosaicIndexX * mosaicSize Dim pointRight As Integer = pointLeft + mosaicSize - 1 Dim pointTop As Integer = mosaicIndexY * mosaicSize Dim pointBottom As Integer = pointTop + mosaicSize - 1 Dim sumR As Integer = 0 Dim sumG As Integer = 0 Dim sumB As Integer = 0 'このモザイク内のすべての色を赤・青・緑それぞれで合計します。 For pointScanY As Integer = pointTop To pointBottom 'ここでの処理は計算は1行ごとに行います。(つまりモザイクのサイズが20であればこのForは20回実行されます。) 'このモザイクの現在の行の色情報が配列 rgbBitsのどの位置にあるか計算します。 Dim bitStartIndex As Integer = pointScanY * bmpData.Stride + pointLeft * 3 Dim bitEndIndex As Integer = pointScanY * bmpData.Stride + pointRight * 3 For bitIndex As Integer = bitStartIndex To bitEndIndex Step 3 If rgbBits.Length > bitIndex Then sumR += rgbBits(bitIndex) sumG += rgbBits(bitIndex + 1) sumB += rgbBits(bitIndex + 2) End If Next Next 'このモザイクの赤・青・緑の平均値を算出します。 Dim aveR As Double = sumR / (mosaicSize * mosaicSize) Dim aveG As Double = sumG / (mosaicSize * mosaicSize) Dim aveB As Double = sumB / (mosaicSize * mosaicSize) '算出した平均値をこのモザイク内に等しくセットします。 For pointScanY As Integer = pointTop To pointBottom Dim bitStartIndex As Integer = pointScanY * bmpData.Stride + pointLeft * 3 Dim bitEndIndex As Integer = pointScanY * bmpData.Stride + pointRight * 3 For bitIndex As Integer = bitStartIndex To bitEndIndex Step 3 If rgbBits.Length > bitIndex Then rgbBits(bitIndex) = CByte(aveR) rgbBits(bitIndex + 1) = CByte(aveG) rgbBits(bitIndex + 2) = CByte(aveB) End If Next Next Next Next '▼色情報の書き込み '算出した色情報を画像に書き込みます。 System.Runtime.InteropServices.Marshal.Copy(rgbBits, 0, bmpData.Scan0, bitCount) bmp.UnlockBits(bmpData) '▼画像の作成(メモリ上で) '新しい色情報を画像 resultImage に書き込みます。 Dim resultImage As New Bitmap(bmp.Width, bmp.Height) Dim g As Graphics = Graphics.FromImage(resultImage) g.DrawImage(bmp, 0, 0) Return resultImage End Function End Class