INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

How to transfer pictures from C# to VB6?

How to transfer pictures from C# to VB6?

(OP)
Hi everyone,

I have to research the fastest way to transfer pictures from a C# application - which generates them - to a VB6 form... if this can be done at all. Animation by replacing must be possible, but the smoother the better. Storing the pictures somewhere on disk and loading them in VB6 is no option. Both the C# end and the VB6 end are mine to develop at the moment.
Currently I can store the picture data (a .NET Bitmap class) in memory and the address from which to start reading is known - but I am a little at a loss on how to proceed.

Assuming that I can read the picture's data into a VB6 array and that the format these bytes represent is known: is there a way to convert the bytes back into an actual picture? What I'm looking for is LoadPicture() that takes a memory address + number of bytes to read form that address as parameters, instead of a string representing a file name. I'm pretty sure the function doesn't exist in VB6, so how can it be implemented?

Any help here will be much appreciated!

Thanks,
Cooz

RE: How to transfer pictures from C# to VB6?

Sure, why not? Whilst VB6 doesn't natively a) have a LoadLibrary that works from a memory address and b) does not understand a .NET bitmap array (really a GDI+ bitmap array) - it does have the ability to use the Microsoft Windows Acquisition library, which knows how to deal with GDI+ bitmap arrays.

We've had a number of threads on the subject on in the past (about WIA, not about C#), and this one, thread222-1678214: Problem loading a picture from an array, should contain relevant info (and links to other supporting threads)

RE: How to transfer pictures from C# to VB6?

But, to summarise, following the assumption that you already have a method for transferring the byte array to VB (pretty easy), and that you have set a reference to the Windows Aquisition Library, then all you need is something like:

CODE

Private Function LoadPictureFromArray(GraphicsArray() As Byte) As StdPicture
    With New WIA.Vector
        .BinaryData = GraphicsArray
        Set LoadPictureFromArray = .ImageFile.FileData.Picture
    End With
End Function 

RE: How to transfer pictures from C# to VB6?

(OP)
Hi strongm,

Yes, I got it working! This is neat.

It looks like I've said a little too much though when I mentioned "Currently I can store the picture data (a .NET Bitmap class) in memory and the address from which to start reading is known". - thinking a C# version of VarPtr would give me the address. And it worked for strings. Oops... not for objects of course. sad The required C# version of ObjPtr is not so easy to implement.

Unless you've a similar splendid idea on this, I think we can consider this thread closed.

Thanks for your input!
Cooz

RE: How to transfer pictures from C# to VB6?

>Currently I can store the picture data (a .NET Bitmap class) in memory and the address from which to start reading is known"

Ah, but you don't need to do that. You should be able to direfctly pass the image as an array. I'm not a C## guru, but here's a (very basic) function that I'd use in VB.NET that should be easily translatable:

CODE

Public Function GetImageBytes(image As System.Drawing.Image) As Byte()
        Dim byteArray() As Byte
        Dim stream As New IO.MemoryStream
        With stream
            image.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp)
            stream.Close()

            byteArray = stream.ToArray()
        End With
        Return byteArray

    End Function 

RE: How to transfer pictures from C# to VB6?

(OP)
Okay, yes that sounds plausible. Here's the C# format, easily translated indeed. And if you'll allow me... you can skip the "With... End With" in your function. wink

CODE --> C#

public byte[] GetImageBytes(Image image)
        {
            var stream = new MemoryStream();
            image.Save(stream, ImageFormat.Bmp);
            stream.Close();
            return stream.ToArray();
        } 

I'll see if I can get my VB6 application to call it.

RE: How to transfer pictures from C# to VB6?

>you can skip the "With... End With"

Indeed. In fact my final version does not have the with ... end with, they were a hangover from a slightly earlier version.

>I'll see if I can get my VB6 application to call it.

I use an ActiveX object to transfer the data and raise an event in VB6 when the data has changed, thus making "Animation by replacing must be possible" almost effortless ...

RE: How to transfer pictures from C# to VB6?

I was intrigued enough to finish an example solution ...

Firstly it requires an ActiveX EXE. In my example this project is called vbDataTransfer, and consists of a module and two classes as below:

CODE --> modGlobals

Option Explicit

Public PrivateTransfer As clsTransfer
Public lCount As Long 

CODE --> clsTransfer

' clsTransfer
' Instancing - PublicNotCreatable
Option Explicit
 
Public Event TransferArrived(arrTransfer() As Byte)
 
Friend Sub RaiseTransferArrived(arrTransfer() As Byte)
    RaiseEvent TransferArrived(arrTransfer)
End Sub 

CODE --> clsConnector

' clsConnector
' Instancing - MultiUse
Option Explicit

Private WithEvents Transfer As clsTransfer
Public Event TransferArrived(arrTransfer() As Byte)
 
Private Sub Class_Initialize()
    If PrivateTransfer Is Nothing Then
        Set PrivateTransfer = New clsTransfer
    End If
    Set Transfer = PrivateTransfer
    lCount = lCount + 1
End Sub
 
Private Sub Class_Terminate()
    lCount = lCount - 1
    If lCount = 0 Then
        Set PrivateTransfer = Nothing
    End If
End Sub
 
' Bubble the event
Private Sub Transfer_TransferArrived(arrTransfer() As Byte)
    RaiseEvent TransferArrived(arrTransfer)
End Sub
 
Public Property Let NewCommand(arrTransfer() As Byte)
    PrivateTransfer.RaiseTransferArrived arrTransfer()
End Property 

This should be compiled and the resulting ActiveX library registered.

Ok, that's the 'complicated' bit ...

And now we need a .NET program that sends a bitmap ... here's the VB.NET version:

CODE --> PictureTransfer

' Requires a COM reference to vbDataTransfer (or whatever you called the class library) to be added to the project
' Windows form should have a picturebox and a command button, picturebox should have an image loaded
Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim test As New vbDataTransfer.clsConnector
        test.NewCommand = GetImageBytes(Me.PictureBox1.Image)
    End Sub

    Public Function GetImageBytes(image As System.Drawing.Image) As Byte()
        Dim stream As New IO.MemoryStream
        image.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp)
        stream.Close()
        GetImageBytes = stream.ToArray()
    End Function

End Class 

Oh, and my attempt at a C# version as well:

CODE --> PictureTransCSharp

// Requires a COM reference to vbDataTransfer (or whatever you called the class library) to be added to the project
// Windows form should have a picturebox and a command button, picturebox should have an image loaded
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        public byte[] GetImageBytes(Image image)
        {
            var stream = new MemoryStream();
            image.Save(stream, ImageFormat.Bmp);
            stream.Close();
            return stream.ToArray();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            var test = new vbDataTransfer.clsConnector();
            test.set_NewCommand(GetImageBytes(pictureBox1.Image));
        } 
    }
} 

And finally the vb program that the bitmap can be sent to ...

CODE --> TransferExample

' assumes user form with picturebox and command button
' assumes reference to WIA added
' and reference added to vbDataTransfer library; you may, of course, have called it something else
Option Explicit

Dim WithEvents appConnector As clsConnector

Private Sub Form_Initialize()
    Set appConnector = New clsConnector
End Sub

Private Sub appConnector_TransferArrived(strTransfer() As Byte)
    Set Picture1.Picture = LoadPictureFromArray(strTransfer)
End Sub

Private Function LoadPictureFromArray(GraphicsArray() As Byte) As StdPicture
    With New WIA.Vector
        .BinaryData = GraphicsArray
        Set LoadPictureFromArray = .ImageFile.FileData.Picture
    End With
End Function 

RE: How to transfer pictures from C# to VB6?

(OP)
Hi strongm,

This looks not too difficult. Thanks for sharing all the details!
One thingie though... I've never registered a VB6 dll; and VB6 dlls in the GAC won't work. Using regsvr32 looks fine initially and I can set a reference to vbDataTransfer without any problems, but then the code doesn't recognize clsConnector. This goes for the sending as well as for the receiving code. Am I overlooking something?

RE: How to transfer pictures from C# to VB6?

To register it properly, try at command line

ActiveXexeName.exe /regserver

(you can also simply double click it in Explorer, which has the same effect)

RE: How to transfer pictures from C# to VB6?

(OP)
strongm, this is a w e s o m e.
Indeed, this is exactly what I wanted... and so elegant! Thank you so much!
I'll have a happy weekend now. I hope you'll have one too. bigsmile

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close