Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitlePixellate a rectangular area in an image
Keywordspixellate, image, DIB, GetDIBits, SetDIBits
CategoriesGraphics
 
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
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated