Thursday, October 23, 2008

Interpolate an array to twice its size in VB.NET

I had an array that I wanted to "interpolate".  The simplified version is the array (one-dimensional) had the following values:

011000

Now this array is a one dimensional array that contains values for an image. For this example, the width of the image is 2 digits.  I wanted to interpolate this array so that the width of the image is 4 digits.

Initially my thought was just to do this:

001111000000

This was simple as I just looped through the original array as such:

for index = 0 to oldarray.length - 1
    newarray[index*2] = oldarray[index]
    newarray[index*2 + 1] = oldarray[index]
end for


But the problem with this is that the old image looked like this:

01
10
00

The new image looks like this:
0011
1100
0000

Which is fine, except when I realized that I interpolated ONLY the WIDTH of the array, and not the height.  What I wanted was something like this:

001100111100110000000000

0011
0011
1100
1100
0000
0000

Now for some reason I couldn't figure this out.  But the solution is actually quite simple.  You have to set 4 values for each one in the old array.  In the above example, I interpolate the width, now I just need to interpolate the height.  Below is the example.

     For index As Integer = 0 To oldarray.length - 1
        If (index > 0 AndAlso (index Mod NEWARRAYWIDTH/ 2))) = 0) Then // I know what the width of the new image will be, and the old one is half as large
          row = row + 1
        End If
        newIndex = index Mod CInt((NEWARRAYWIDTH / 2))
        nearray((row * 2) * NEWARRAYWIDTH + (newIndex * 2)) = oldarray(index)
        nearray((row * 2) * NEWARRAYWIDTH + ((newIndex * 2) + 1)) = oldarray(index)
        nearray(((row * 2) + 1) * NEWARRAYWIDTH + (newIndex * 2)) = oldarray(index)
        nearray(((row * 2) + 1) * NEWARRAYWIDTH + ((newIndex * 2) + 1)) = oldarray(index)
      Next

I installed VS 2003 after VS 2005

 I initially has VS 2003 and then installed VS 2005, no problems.  However, I had to re-install my operating system and because I had deadlines, when I got back up and running, I just installed VS 2005 because most of my work was with that.  But recently, I had a program that wouldn't convert from vs 2003 to vs 2005, so I needed to look at it in 2003.  So I went back and installed VS 2003.  Nothing really bad happened, except when I doubled on a VS 2005 solution, it tries to open it in VS 2003 and I get an error.  I have to right click on the solution and select Microsoft Visual Studio Version Selector which then opens the solution in VS 2005.  I haven't found a better solution.

Thursday, October 16, 2008

Missing MSVCR80.dll and COREDLL.DLL

I built an application in VS2005 and in dependency walker it shows that it was missing MSVCR80.dll, so I did a search on my machine and got one that was in the C:\Program Files\Microsoft Visual Studio 8\VC\cd\DLL\mipsiv\.  But in dependency walker, the MSVCR80.dll was missing another dll called COREDLL.DLL, when I searched for this file on my machine I couldn't find it.  I figured I was screwed.
 
But then I realized that I had multiple copies of MSVCR80.dll on my machine, the one in the above directory was 47 KB, there was another one in the C:\Windows\WinSxS\x80_Microsoft.VC80....... directory that was 612K, and it seemed that I had a lot of versions that were 612 KB.  When I opened this in dependency walker it didn't need th COREDLL.DLL.  So I was golden.
 

Wednesday, October 1, 2008

How to Save the Output of a Paint Routine in .NET to a Bitmap File or save the image from a picturebox to a bitmap file

Another way to say this is how to save the image from a picturebox to a bitmap file.

I have a Picture box where I load an image at design time.  At runtime, I allow the user the doodle on the image.  I would like to save this image to a bitmap file.  The way I allow the user to draw on the image is through the mousedown and mousemove event I write to an arraylist, and in the PictureBox's paint routine I draw out the contents of the arraylist.  When I try to do a Picturebox1.Image.Save, it doesn't work in that it saves the original image that I loaded at design time, not the one that I just drew on in mousedown and mousemove.  There are two ways the do this.  The harder method is below.  What it does is it creates a tempimage, then it draws to this temp image (what I am assuming here is that you've moved the code from your PictureBox1.Paint routine to a stand alone routine called PaintPictureBox1, this way you can call it from two places), and finally it returns the temp image.

Public Function CurrentPictureBox() as Bitmap

        Dim iNewWidth As Integer, iNewHeight As Integer
        iNewWidth = Int(PictureBox1.Image.Width)
        iNewHeight = Int(PictureBox1.Image.Height)

        tempImage = New Bitmap(iNewWidth, iNewHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb)        
        g = Graphics.FromImage(tempImage)      

        g.DrawImage(PictureBox1.Image, 0, 0, iNewWidth, iNewHeight)
        PaintPictureBox1(g)
    return tempImage
End Sub


The second method is simpler, in that it takes advantage of .NETs DrawToBitmap routine.

Public Function CurrentPictureBox() as Bitmap
            Dim tempImageAs New Drawing.Bitmap(PictureBox1.Image.Width, PictureBox1.Image.Height)
            PictureBox1.DrawToBitmap(tempImage, New Rectangle(0, 0, bmp.Width, bmp.Height))
            return tempImage
End Sub