Avian Waves : Blog
Topic: Tech
Search Blog
 
Recent Comments
Bulk Local Administrator Password Management Tool (15)
rcmichelle: Last time I forgot my password and tried...

Easy Way to Change Permissions on the Windows Server Scheduled Tasks Folder (C:\Windows\Tasks) (22)
4Fingus: Thank you so much. You have saved me alot of...

Mystery of the Missing msnmsn.inf on XP SP3 (24)
jo w: Thanx m8, it's even brilliant for those who are...

Delegating "Power Options" Management to Limited Users in XP (6)
Alessandro Stillitano: Hi :)I can report that on a Lenovo T410i the...
Last 15 Posts
Archives
September, 2010 (1)
July, 2010 (1)
June, 2010 (1)
April, 2010 (2)
March, 2010 (1)
January, 2010 (1)
November, 2009 (1)
October, 2009 (3)
July, 2009 (1)
June, 2009 (4)
April, 2009 (1)
March, 2009 (1)
Blog posts are currently filtered by topic. Click here to view all posts.
Posted By Timothy • Topic: Tech
Nov 22, 2009 5:45 PM EDT

I had a need to directly manipulate the bytes in a bitmap for my VB.Net app for Windows Phone.  I found quite a few articles with The Google on how to do this in C#, using the unsafe keyword.  That's a perfectly fine way of doing it for C# users.  However, VB.Net does not have anything like the unsafe keyword, so there is no way to run unsafe (unmanaged) code blocks.  Philosophically, this might be a "good" thing to Managed Code purists.  I'm actually neutral on the issue.  Still, just because you can't do arbitrary pointer and memory manipulation in VB.Net does not mean you can't do this very simple thing (dimming the color brightness of each byte of a bitmap).  It's pretty easy and I can't believe nobody out there has posted how to do it this way VB.Net or C#.  I came up with this code for the Compact Framework for Windows Phone specifically, but it will also work in the big Framework for big Windows.  It will work in both VB.Net and C# just fine.

The key to this method is using the Marshal.Copy method.  This copies a block of memory from an IntPtr to various types of arrays and then back again.  Whereas the unsafe method directly manipulates the bytes in the bitmap, this code block copies the unmanaged bytes to an array, manipulates them, then copies them back to the unmanaged buffer.  Using the 'unsafe' method is likely a hair faster, but in real world performance metrics, even on Windows Phone you would be hard pressed to see any noticeable difference between the two.  Copying blocks of memory is a very fast operation.

This code adjusts the brightness of a bitmap, dimming it by half (a bit shift of >>1 for each color component of each pixel).  Windows Phone natively uses 16bit bitmaps ('565' format, as in RRRRRGGGGGGBBBBB).  The below code block can be adjusted to work with 24 and 32 bit bitmaps as needed.  It's actually easier to use 24 and 32 bit bitmaps as you just manipulate the brightness of  individual Byte primitives without needing to break apart the Int16 (short) using bit masks, as below.  However, the act of converting the 16 bit bitmap to a 32 bit bitmap on Windows Phone seems to cause a significant a performance hit!  So don't do that on Windows Phone.  Stay with the 16-bit bitmap and use bit masks, as I did below.  For big Windows, you will want to use 32 bit bitmaps, not 16 bit bitmaps.

Private Sub DimBitmapByHalf(ByRef bmp As Bitmap)
  Dim bmd As Imaging.BitmapData = bmp.LockBits(New Rectangle(0, 0, bmp.Width, bmp.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format16bppRgb565)
  Try
    Dim bufLen As Integer = (bmd.Stride * bmd.Height) / 2 ' Because bmd.Stride and bmd.Height are in units of 8-bit bytes
    Dim buf(bufLen - 1) As Short
    Dim r As Short
    Dim g As Short
    Dim b As Short

    System.Runtime.InteropServices.Marshal.Copy(bmd.Scan0, buf, 0, bufLen)
    For i = 0 To bufLen - 1
      '                              RRRRR GGGGGG BBBBB
      r = (buf(i) >> 1) And &H7800 ' 01111 000000 00000
      g = (buf(i) >> 1) And &H3E0  ' 00000 011111 00000
      b = (buf(i) >> 1) And &HF    ' 00000 000000 01111
      buf(i) = r Or g Or b
    Next
    System.Runtime.InteropServices.Marshal.Copy(buf, 0, bmd.Scan0, bufLen)
  Finally
    bmp.UnlockBits(bmd)
  End Try
End Sub

Trackbacks :
Send trackbacks to this URL:
http://www.avianwaves.com/Blog/track.aspx?id=176
In your blog post, you must link back to my post using this URL:
http://www.avianwaves.com/Blog/default.aspx?id=176
Add Comment :
Name :
Email :
URL (Optional) :
       
Comments :
Allowed BBCode Tags : LINK (URL), BOLD, ITALIC, UNDERLINE, QUOTE


By posting a comment to this blog, I agree to the blog rules.

This Avian Waves blog is powered by a modified version of Presstopia Blog




Avian Waves Logo