Pixellation replaces an image with large pseudo-pixels that each represent the average color of the area they represent.
This program loops over the image in pseudo-pixel blocks of a specified size. For each block, it takes the average of the colors in the block and sets all pixels in the block to that average color.
If you examine the code carefully, you'll see how the program uses Do loops to ensure that every pixel is considered even if it is near the edge of the image. For example, suppose the image has 20x16 pixels and the block size is 8. The image will contain 4 blocks plus two 4x8 partial blocks on the right. The xmax and ymax values allow the program to average over these partial blocks.
Note that averaging over the partial blocks makes them less "averaged" than the other blocks (their data is less disguised). An alternative might be to cut any partial blocks out of the image completely.
|
Private Sub cmdGo_Click()
Dim block_size As Integer
Dim bitmap_info As BITMAPINFO
Dim pixels() As Byte
Dim bytes_per_scanLine As Integer
Dim pad_per_scanLine As Integer
Dim X As Integer
Dim Y As Integer
Dim i As Integer
Dim j As Integer
Dim total_r As Long
Dim total_g As Long
Dim total_b As Long
Dim xmax As Integer
Dim ymax As Integer
Dim num_pixels As Integer
block_size = CInt(txtBlockSize.Text)
' Prepare the bitmap description.
With bitmap_info.bmiHeader
.biSize = 40
.biWidth = picFrom.ScaleWidth
' Use negative height to scan top-down.
.biHeight = -picFrom.ScaleHeight
.biPlanes = 1
.biBitCount = 32
.biCompression = BI_RGB
bytes_per_scanLine = ((((.biWidth * .biBitCount) + _
31) \ 32) * 4)
pad_per_scanLine = bytes_per_scanLine - (((.biWidth _
* .biBitCount) + 7) \ 8)
.biSizeImage = bytes_per_scanLine * Abs(.biHeight)
End With
' Load the bitmap's data.
ReDim pixels(1 To 4, 1 To picFrom.ScaleWidth, 1 To _
picFrom.ScaleHeight)
GetDIBits picFrom.hdc, picFrom.Image, _
0, picFrom.ScaleHeight, pixels(1, 1, 1), _
bitmap_info, DIB_RGB_COLORS
' Modify the pixels.
Y = 1
Do While Y < picFrom.ScaleHeight
ymax = Y + block_size
If ymax >= picFrom.ScaleHeight _
Then ymax = picFrom.ScaleHeight
X = 1
Do While X < picFrom.ScaleWidth
xmax = X + block_size
If xmax >= picFrom.ScaleWidth _
Then xmax = picFrom.ScaleWidth
' Get the total color for this block.
total_r = 0
total_g = 0
total_b = 0
For i = X To xmax
For j = Y To ymax
total_r = total_r + pixels(pixR, i, j)
total_g = total_g + pixels(pixG, i, j)
total_b = total_b + pixels(pixB, i, j)
Next j
Next i
' Set the color of this block.
' Set the blue component to 255.
num_pixels = (xmax - X + 1) * (ymax - Y + 1)
total_r = total_r / num_pixels
total_g = total_g / num_pixels
total_b = total_b / num_pixels
For i = X To xmax
For j = Y To ymax
pixels(pixR, i, j) = total_r
pixels(pixG, i, j) = total_g
pixels(pixB, i, j) = total_b
Next j
Next i
X = X + block_size
Loop
Y = Y + block_size
Loop
' Display the result.
SetDIBits picTo.hdc, picTo.Image, _
0, picFrom.ScaleHeight, pixels(1, 1, 1), _
bitmap_info, DIB_RGB_COLORS
picTo.Picture = picTo.Image
End Sub
|