Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PLEASE CONVERT TO VB!

3 views
Skip to first unread message

Timothy Taylor

unread,
Jun 5, 2003, 12:41:34 AM6/5/03
to
could somebody PLEASE convert this to VB for me, i've tried EVERYTHING but i
can't get it to work, so if somebody who actually knows C# could do it for
me i would REALLY love that!

Thanks you SOOO much in advance,

-Tim

using System;

using System.Drawing;

using System.IO;

using System.Runtime.InteropServices;

namespace SaveThisImage

{

/// <summary>

/// Summary description for BitmapSaver.

/// </summary>

public class BitmapSaver

{

/// <summary>

/// Saves an image (image) at the location defined (szPath). This uses the
generic

/// 24-bit format, so the image is not compressed.

/// </summary>

/// <param name="image">The bitmap image to store</param>

/// <param name="szPath">The path to save at</param>

static public void SaveBitmapToFile(Image image, string szPath)

{

FileStream fs = File.Create(szPath);

SaveBitmapToStream(image, fs);

fs.Close();

}

/// <summary>

/// Saves an image (image) at the location defined (szPath). This uses the
generic

/// 24-bit format, so the image is not compressed.

/// </summary>

/// <param name="image">The bitmap image to store</param>

/// <param name="stream">The stream to save to</param>

static public void SaveBitmapToStream(Image image, Stream stream)

{

/*

* Sort of from
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_4v1h.asp.

* The below is hardcoded to support saving a 24-bit bitmap. Slight changes
would be made to certain

* constants in order to save 16-bit or 256-color (8-bit) or whatever. The
resulting file is probably

* the largest of any image format, which is at the benefit of speed. There
are other ways of saving

* bitmaps (such as using color indexing) which will reduce the bitmap size,
but they also add

* performance hits.

*

* ---Data--- ---Bytes---

* "BM" 0x00-0x01

* File Size 0x02-0x05

* Reserved 1 0x06-0x07

* Reserved 2 0x08-0x09

* Constant 0x36 0x0A

* Constant 0x00 0x0B-0x0D

* Constant 0x28 0x0E (This byte is always 0x28)

* Constant 0x00 0x0F-0x11 (These bytes are always 0x00)

* Bitmap Width 0x12-0x15

* Bitmap Height 0x16-0x19

* Constant 0x01 0x1A

* Constant 0x00 0x1B

* Constant 0x18 0x1C

* Constant 0x00 0x1D-0x21

* Image byte size 0x22-0x25

* Constant 0x00 0x26-0x35

* Pixels 0x36-Rest

* These are 3-byte RGB values for pixels starting at bottom left, moving
right.

* They are in G-B-R order, and you have to remember to make the full stride
(row) a

* multiple of 4, meaning that if you have a width of 3, that's only 9 bytes
and you

* have to pad with 3 to round it to the next multiple of 4.

*/

// This should probably be done a little more carefully

Bitmap bm = (Bitmap) image;

const int BYTES_PER_PIXEL = 3;

// Need 0x36 bytes for the headers, plus all of the pixel data, so round up
to nearest 4

int nBytes = 0x36 + (bm.Height * ((BYTES_PER_PIXEL * bm.Width) + 0x03) &
~0x03);

byte[] BitmapData = new byte[nBytes];

BitmapData[0x00] = (byte) 'B';

BitmapData[0x01] = (byte) 'M';

// I'm sure there's a better way to do this but I didn't look up the C#
equiv of memcpy

BitmapData[0x02] = (byte) nBytes;

BitmapData[0x03] = (byte) (nBytes >> 8);

BitmapData[0x04] = (byte) (nBytes >> 16);

BitmapData[0x05] = (byte) (nBytes >> 24);

BitmapData[0x0A] = 0x36;

BitmapData[0x0E] = 0x28;

BitmapData[0x12] = (byte) bm.Width;

BitmapData[0x13] = (byte) (bm.Width >> 8);

BitmapData[0x14] = (byte) (bm.Width >> 16);

BitmapData[0x15] = (byte) (bm.Width >> 24);

BitmapData[0x16] = (byte) bm.Height;

BitmapData[0x17] = (byte) (bm.Height >> 8);

BitmapData[0x18] = (byte) (bm.Height >> 16);

BitmapData[0x19] = (byte) (bm.Height >> 24);


BitmapData[0x1A] = 0x01;

BitmapData[0x1C] = 0x18;

BitmapData[0x22] = (byte) (nBytes - 0x36);

BitmapData[0x23] = (byte) ((nBytes - 0x36) >> 8);

BitmapData[0x24] = (byte) ((nBytes - 0x36) >> 16);

BitmapData[0x25] = (byte) ((nBytes - 0x36) >> 24);

// Stripping bitmap from bottom left, moving right through the row, then up
to the next row

int index = 0x36;

for (int h = bm.Height - 1; h >= 0; h--)

{

for (int w = 0; w < bm.Width; w++)

{

int c = bm.GetPixel(w, h).ToArgb();

BitmapData[index++] = (byte) c;

BitmapData[index++] = (byte) (c >> 8);

BitmapData[index++] = (byte) (c >> 16);

}

// Padding the end of the row

// (if I RTFM'd this wouldn't have taken so long to figure out :-)

int xtra = (bm.Width * 3) % 4;

if (xtra != 0)

{

index += 4 - xtra;

}

}

// Write the bytes to the stream

stream.Write(BitmapData, 0, BitmapData.Length);

}

}

}


Pete Vickers

unread,
Jun 5, 2003, 2:55:30 AM6/5/03
to
Hi,
there are a couple of sites you could try to do this automatically,
http://www.aspalliance.com/aldotnet/examples/translate.aspx ,
http://www.kamalpatel.net/ConvertCSharp2VB.aspx

Pete

--
Pete Vickers
Microsoft Windows Embedded MVP
HP Business Partner - Compaq Solutions Alliance
http://www.gui-innovations.com

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message
news:etEFBzxK...@TK2MSFTNGP12.phx.gbl...

Timothy Taylor

unread,
Jun 5, 2003, 6:15:53 PM6/5/03
to
Yes, i tried those, all of them, but it just doesn't work, i've tried all i
can to understand the logic and everything behind it, but I just can't
understand C#! So no matter what i change, it doesn't work, so i just need
a smart C# and VB programmer that gets what's going on that can duplicate it
in VB!

Thank you anyway,

-Timothy

"Pete Vickers" <pete at gui - innovations dot com> wrote in message
news:%23gsvv9y...@TK2MSFTNGP12.phx.gbl...

Bob Nicholls

unread,
Jun 7, 2003, 12:29:10 PM6/7/03
to
I converted the following from some other bit of C#. Appologies to the
original author for not referencing him/her.

Hope it is of use.

Bob

Imports System.IO

Imports System.Runtime.InteropServices

Module BMP

Public Function SaveBMP(ByVal theBMP As Bitmap, ByVal filename As String) As
Boolean

'Given a bitmap, which could be from a PictureBox (picturebox.image), saves
the images to

'filename (of .bmp file format)

Dim c As Color

Dim pad As Boolean = theBMP.Width Mod 2 = 1, p As Long = 0

Dim padding As Short = 0

If pad Then padding = 1

Dim pixels(theBMP.Height * (theBMP.Width + padding) * 3) As Byte

Dim x As Long, y As Long

For y = theBMP.Height - 1 To 0 Step -1

For x = 0 To theBMP.Width - 1

c = theBMP.GetPixel(x, y)

pixels(p) = c.B

p += 1

pixels(p) = c.G

p += 1

pixels(p) = c.R

p += 1

Next

If pad Then

p += 3

End If

Next

Dim outBmp As Byte()

outBmp = CreateBitmap(theBMP.Width, theBMP.Height, pixels)

Dim fs As New FileStream(filename, FileMode.OpenOrCreate)

' Create the writer for data.

Dim w As New BinaryWriter(fs)

w.Write(outBmp)

w.Close()

fs.Close()

SaveBMP = True

End Function

Dim sizeBFH As Integer = 14 'sizeof(BITMAPFILEHEADER)

Private Function CreateBitmap(ByVal width As Integer, ByVal height As
Integer, ByVal bitmapData As Byte()) As Byte()

' Calculate bitmap size - 3 bytes per pixel

' Bitmap scanlines must be aligned at 16 bit boundary.

Dim padding As Short = 0

If (width Mod 2) = 1 Then

'Throw New ArgumentException("Width must be an even number")

padding = 1

End If

Dim WidthHelper As Long = (width * 3) + (width Mod 4)

Dim nSize As Integer = sizeBFH + Marshal.SizeOf(New BITMAPINFOHEADER) +
(width + padding) * height * 3

Dim data() As Byte = New Byte(nSize) {}

Dim bfh() As Byte = New Byte(sizeBFH) {}

BitConverter.GetBytes(CInt(&H4D42)).CopyTo(data, 0)

BitConverter.GetBytes(nSize).CopyTo(data, 2)

Dim bfhOffBits As Integer = CType((sizeBFH + Marshal.SizeOf(New
BITMAPINFOHEADER)), Integer)

BitConverter.GetBytes(bfhOffBits).CopyTo(data, 10)

Dim bi As BITMAPINFOHEADER = New BITMAPINFOHEADER

bi.biSize = System.Convert.ToUInt32(Marshal.SizeOf(bi))

bi.biBitCount = Convert.ToUInt16(24) ' Creating RGB bitmap. The following
three members don't matter

bi.biClrUsed = Convert.ToUInt32(0)

bi.biClrImportant = Convert.ToUInt32(0)

bi.biCompression = Convert.ToUInt32(0)

bi.biHeight = height

bi.biWidth = width

bi.biPlanes = Convert.ToUInt16(1)

Dim cb As Integer = (CLng(bi.biHeight) * CLng(bi.biWidth + padding) *
System.Convert.ToInt32(bi.biBitCount) / 8) '8 is bits per byte

bi.biSizeImage = System.Convert.ToUInt32(cb)

bi.biXPelsPerMeter = &HB12 ' 72 ppi, 96 would work well too

bi.biYPelsPerMeter = &HB12 ' 72 ppi

Dim hdr() As Byte = GetBytes(bi)

Buffer.BlockCopy(hdr, 0, data, sizeBFH, hdr.Length)

Buffer.BlockCopy(bitmapData, 0, data, bfhOffBits,
System.Math.Min(bitmapData.Length, cb))

Return data

End Function

' This works only for default-aligned structure.

' It does not work for BITMAPFILEHEADER because bfSize is not aligned to
DWORD boundary

' Unfortunately CF does not allow specifying structure member alignment

Private Function GetBytes(ByVal o As Object) As Byte()

Dim size As Integer = Marshal.SizeOf(o.GetType())

Dim p As IntPtr = LocalAlloc(GPTR, size)

Marshal.StructureToPtr(o, p, False)

Dim ret() As Byte = New Byte(size) {}

Marshal.Copy(p, ret, 0, size)

LocalFree(p)

Return ret

End Function

Structure BITMAPINFOHEADER

Public biSize As System.UInt32

Public biWidth As Integer

Public biHeight As Integer

Public biPlanes As System.UInt16

Public biBitCount As System.UInt16

Public biCompression As System.UInt32

Public biSizeImage As System.UInt32

Public biXPelsPerMeter As Integer

Public biYPelsPerMeter As Integer

Public biClrUsed As System.UInt32

Public biClrImportant As System.UInt32

End Structure

Structure BITMAPFILEHEADER

Public bfType As System.UInt16

Public bfSize As System.UInt32

Public bfReserved1 As System.UInt16

Public bfReserved2 As System.UInt16

Public bfOffBits As System.UInt32

End Structure

Const GPTR As Integer = &H40

<DllImport("KERNEL32.dll", SetLastError:=True)> _

Private Function LocalAlloc(ByVal uFlags As Integer, _

ByVal uBytes As Integer) As IntPtr

End Function

<DllImport("KERNEL32.dll", SetLastError:=True)> _

Private Function LocalFree(ByVal hMem As IntPtr) As IntPtr

End Function

End Module

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message

news:O0W4LA7K...@tk2msftngp13.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 1:16:57 AM6/9/03
to
Thank you Bob! Finally VB code! :)

However, it has an error on this line of code saying
"MissingMethodException". do you know why?


Dim p As IntPtr = LocalAlloc(GPTR, size)

Thanks,

-Tim

"Bob Nicholls" <b...@notning.com> wrote in message
news:e$ZhtHRLD...@TK2MSFTNGP09.phx.gbl...

Bob Nicholls

unread,
Jun 9, 2003, 3:13:18 AM6/9/03
to
Tim,

I can't think why at the moment and I'm just leaving to go on holiday for
the week. On my return I'll try to remember to check to see if you or
someone else has managed to fix it.

One thought, do you have another method of the same name, LocalAlloc, in
your code?

Bob

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message

news:eSECdZkL...@TK2MSFTNGP10.phx.gbl...

Bob Nicholls

unread,
Jun 9, 2003, 3:32:01 AM6/9/03
to
One very final thought, did my code survive the cut and past into your
development environment? I have just copied the code from my post into a new
project and it worked but I had to clean up the line breaks (NB note the
line continuations around the LocalAlloc definition).

And just in case it wasn't obvious you call the code like this:

SaveBMP(picbox.Image, "test.bmp")

Bob

"Bob Nicholls" <b...@notning.com> wrote in message

news:ere7ZalL...@TK2MSFTNGP10.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 2:00:15 PM6/9/03
to
Ok, yes i had to get the lines together but that was before the error, i had
a lot of others before i put the lines together :)

Yeah, it's pretty ovbious, but do you put the whole path ("\My
Documents\image1.bmp") or just the name itself ("image1.bmp")?

Thank you very much bob, and have fun on your vacation!

-Timothy

"Bob Nicholls" <b...@notning.com> wrote in message

news:eleP3klL...@TK2MSFTNGP11.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 2:00:55 PM6/9/03
to
No i don't, thanks for the idea though, ok, have fun,

-Tim
"Bob Nicholls" <b...@notning.com> wrote in message

news:ere7ZalL...@TK2MSFTNGP10.phx.gbl...

Alex Feinman [MVP]

unread,
Jun 9, 2003, 2:19:09 PM6/9/03
to
It does not work because references to kernel32 should be actually
coredll.dll

<DllImport("KERNEL32.dll", SetLastError:=True)>
should be
<DllImport("coredll.dll", SetLastError:=True)>

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message

news:u$DIWErLD...@TK2MSFTNGP10.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 7:59:53 PM6/9/03
to
Thank you alex, it works great now,

However, is there a way to set one image as another shrinked?

For example, can I take an image that has pixels of 1600 x 1200 and save or
set another image to be the same image but as like pixels 800 x 600 or
something?

Thank you so much,

-Tim

"Alex Feinman [MVP]" <publi...@alexfeinman.com> wrote in message
news:OYlOgOrL...@TK2MSFTNGP11.phx.gbl...

Alex Feinman [MVP]

unread,
Jun 9, 2003, 8:36:30 PM6/9/03
to
You need to look up an image scaling algorithm. For the conversion like one
you asked about (1600x1200->800x600) you can simply skip every other pixel
and every other scanline. Unfortunately if the original size is not a
multiple of the target size, there is some fancy algorithm required.
Something like it described here:
http://www.codeproject.com/cs/media/imageprocessing4.asp
YOu may want to search google for "image scaling VB.NET"

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message

news:%23tHi8Mu...@tk2msftngp13.phx.gbl...

Chris Tacke, eMVP

unread,
Jun 9, 2003, 8:47:17 PM6/9/03
to
If you DrawImage into a Graphics object, you can set the destination rect to
be smaller than the source rect and it will shrink it for you. Not sure how
clean the end result will look - I assume it's doing a StretchBlt under the
hood so it won't be great.

-Chris

"Timothy Taylor" <timoth...@pocketelite.com> wrote in message

news:#tHi8MuL...@tk2msftngp13.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 9:55:35 PM6/9/03
to
How would i send that to a system.drawing.image?

and then from there save it.

Any code would be wonderful, thanks,

-Tim

"Chris Tacke, eMVP" <cta...@NOinnovativedssSPAM.com> wrote in message
news:upQhdnuL...@TK2MSFTNGP10.phx.gbl...

Timothy Taylor

unread,
Jun 9, 2003, 11:07:14 PM6/9/03
to
Oh boy, that sounds tough.

Well how would you "simply skip every other pixel"?

Thanks,

-Tim

"Alex Feinman [MVP]" <publi...@alexfeinman.com> wrote in message

news:uZWKXhuL...@TK2MSFTNGP12.phx.gbl...

Bob Nicholls

unread,
Jun 16, 2003, 4:09:52 AM6/16/03
to
Alex,

Thanks for fixing it.

Bob

"Alex Feinman [MVP]" <publi...@alexfeinman.com> wrote in message
news:OYlOgOrL...@TK2MSFTNGP11.phx.gbl...

0 new messages