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 rectangle. For example, suppose the rectangle 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 Pixellate(ByVal block_size As Integer, ByVal x1 _
As Single, ByVal y1 As Single, ByVal x2 As Single, _
ByVal y2 As Single)
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
Dim temp As Single
' Make sure x1 <= x2, y1 <= y2.
If x1 > x2 Then
temp = x1
x1 = x2
x2 = temp
End If
If y1 > y2 Then
temp = y1
y1 = y2
y2 = temp
End If
' Add 1 to go from 0 to ScaleXxx - 1 to
' 1 to ScaleXxx.
x1 = x1 + 1
y1 = y1 + 1
x2 = x2 + 1
y2 = y2 + 1
' 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 = y1
Do While Y <= y2
ymax = Y + block_size
If ymax > y2 Then ymax = y2
X = x1
Do While X <= x2
xmax = X + block_size
If xmax > x2 Then xmax = x2
' 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
|