IntPtr zu Bitmap in eine PictureBox?

Asterix-Ac

Erfahrenes Mitglied
Hi Community,

ich habe mir den Wrapper für die Twain API von Codeproject.com (Projektseite) gesaugt und habe sie in meine App eingebaut. Doch ich komme damit noch nicht ganz zurecht.
Der Wrapper liefert mir einen IntPtr zurück und instaziiert ein neues MDI-Child.
In dem Child pinselt er auf den Background das Image (weiß der Teufel, wie er das umgerechnet bekommen hat.). Aber genau das ist es, was ich verstehen muss, weil ich das Image nicht auf den Background haben möchte, sondern in eine PictureBox. Aber wie geht das ? Hat da jemand eine Idee?

Danke schonmal im Vorraus. :)

Asterix :confused:
 
Hy,

Danke für die Infos. Leider hat es nicht funktioniert.
Ich habe es probiert mit :
Code:
pictureBox1.Image = new Image.FromHbitmap(IntPtr)
Ich bekomme dann immer eine Exception, nach dem scannen, wenn das neue
child erstellt werden soll.
Das Problem ist, ich kann nicht debuggen, da ich zu Hause keinen Scanner habe und ich zum probieren immer ins Icafe laufen muss, wo nur das normale Framework installiert ist. :(

Asterix :confused:
 
Hi Comunity,

alles klar ... nun hat es geklappt.
Auf der Tutorial-Seite von Codeprojekt (s.o.) habe ich mir das original nochmal angeschaut und bin zu dem Schluß gekommen, dass ich keinen IntPtr zurückbekomme von der TwainLib sondern eine ArrayList mit IntPtr'ern.
Das half mir aber erst nicht weiter, doch dann habe ich nochmal in dem MessageBoard der Seite nachgeschaut und da hat jemand eine Methode gepostet, die aus der ArrayList ein Bitmap macht (eigentlich unlogisch).
Aber ... Was sich hinter den IntPtr'ern verbirgt, sind GDI-Bitmaps.
Und das ist dann kein Problem mehr, die in eine PictureBox reinzubekommen.
Die Methode (muss übrigens in die MainFrame.cs in die TwainGui Class eingetragen werden) fuktioniert aber so nicht, da sie die Variable i nicht kennt.
Da aber immer nur 1 Bild gescannt wird und sich dann der Dialog vom Twain-Treiber automatisch schließt, enthällt die ArrayList immer nur ein Element.
Das kann man ausnutzen und einfach int i = 0; als erste Zeile in die Methode schreiben .... und voila ... es funktioniert ... :)
Da man ja nun ein ein Bitmap in der Hand hat, kann man das ja der PicForm übergeben (aber ... da es sich ja um nur 1 Bitmap handelt, einfach die Schleife in der MainFrame.cs auskommentieren und antstatt dem IntPtr das Bitmap beim instanziieren übergeben.
Alles an Code in der PicForm kann man getrost über Board werfen. Man pappt einfach eine PictureBox in die Form und im Konstruktor castet(richtig geschrieben?) man das erhaltene Bitmap in ein Image und weist das dann der PictureBox zu .

Fertig. ;-)

Asterix
 
Bitmap aus Arraylist

Hi Community,

Dein Beitrag hat mir sehr weitergeholfen. Allerdings funktioniert es bei mir noch nicht, weil ich immer noch nicht weiss, wie man aus dieser ArrayList ein Bitmap macht. Ich benötige also diese Methode bzw. die Info, wo ich die Methode auf dem MessageBoard finden kann.

Vielen Dank im Voraus

R. Brunetti
 
Hi Brunetti,

tschuldige bitte, dass ich erst jetzt antworte, aber ich habe diesen Beitrag erst jetzt wieder gelesen.

Das Messageboard ist auf der Projektseite, die ich im ersten Beitrag oben gepostet habe, ganz unten. Du must Dich ein wenig durchklicken, bis Du die Methode findest. Habe sie gerade nicht zu Hand, da ich in einem ICafe sitze.

Asterix
 
Hi Asterix,

vielen Dank für Deine Hilfe. Brauchst Dich doch nicht entschuldigen. Ich bin doch schon froh, dass Du Dich überhaupt mal meldest.

Ich habe auf Codeprojekt auch etwas gefunden, komme aber trotzdem noch nicht ganz klar. Es ist sicherlich nur eine Kleinigkeit.

Ich wäre Dir überaus dankbar, wenn Du mir die Methode bzw. den Link, oder noch besser ein Beispielprojekt zusenden würdest.

Ich habe zusätzlich noch das Problem die Sache in vb.net zu übersetzen.

Da ich einen Computerservice habe, kann ich Dir vielleicht auch irgendwie weiter helfen. (z.B. günstige Preise, beim Coden oder sonst irgendwie)

Habe mir mal kurz Deine HP angekuckt. Sehr gelungen, weiter so.

Viele Grüsse
R. Brunetti
 
Hi Brunetti,

hier habe ich die komplette Methode :
Code:
public Bitmap GetBitMap(ArrayList alPics)
{
	int i=0; // das habe ich der Methode hinzugefügt
	Rectangle rPic = new Rectangle(0,0,0,0);
	IntPtr ipNonLockedBitMap = (IntPtr)alPics[i];
	IntPtr ipBitMap = GlobalLock(ipNonLockedBitMap); // TODO: Grab GlobalLock & GlobalFree from PicForm.cs
	BITMAPINFOHEADER bmihInfo = new BITMAPINFOHEADER(); // TODO: Grab BITMAPINFOHEADER from PicForm.cs
	Marshal.PtrToStructure(ipBitMap, bmihInfo);
	rPic.X = rPic.Y = 0;
	rPic.Width = bmihInfo.biWidth;
	rPic.Height = bmihInfo.biHeight;

	if( bmihInfo.biSizeImage == 0 )
		bmihInfo.biSizeImage = ((((bmihInfo.biWidth * bmihInfo.biBitCount) + 31) & ~31) >> 3) * bmihInfo.biHeight;

	int p = bmihInfo.biClrUsed;
	if( (p == 0) && (bmihInfo.biBitCount <= 8) )
		p = 1 << bmihInfo.biBitCount;
	p = (p * 4) + bmihInfo.biSize + (int) ipBitMap;

	IntPtr ipPixel = (IntPtr)p;

	Bitmap bmp = new Bitmap(rPic.Width, rPic.Height);
	Graphics g = Graphics.FromImage((Image)bmp);
	IntPtr hdc = g.GetHdc();

	SetDIBitsToDevice(hdc, 0, 0, bmp.Width, bmp.Height, 0, 0, 0, bmp.Height, ipPixel, ipBitMap, 0);
	g.ReleaseHdc(hdc);

	if (ipNonLockedBitMap != IntPtr.Zero)
	{
		GlobalFree(ipNonLockedBitMap);
		ipNonLockedBitMap = IntPtr.Zero;
	}
	return bmp;
}

hier die Aufrufe für die Twain
Code:
bool IMessageFilter.PreFilterMessage( ref Message m )
{
	try
	{
		TwainCommand cmd = tw.PassMessage( ref m );
		if( cmd == TwainCommand.Not )
			return false;

		switch( cmd )
		{
			case TwainCommand.CloseRequest:
			{
				EndingScan();
				tw.CloseSrc();
				break;
			}
			case TwainCommand.CloseOk:
			{
				EndingScan();
				tw.CloseSrc();
				break;
			}
			case TwainCommand.DeviceEvent:
			{
				break;
			}
			case TwainCommand.TransferReady:
			{
				ArrayList pics = tw.TransferPictures();
				Bitmap bmp = GetBitMap(pics);
				break;
			}
		}
	}
	catch(Exception ex)
	{
		MessageBox.Show(ex.Message);
	}
}
den Rest solltest Du Dir selber zusammenbasteln können.
Zu VB.NET kann ich Dir nicht weiterhelfen, da ich VB nicht kann.
Das müßtest Du schon selber machen. Aber es ist doch eh alles .NET.
Damit kannst Du doch Sprachenunabhängig programmieren.
Mache Dir eine DLL aus der ArrayList2Bitmap - Methode. Kompiliere sie und füge einen Verweis in Dein Projekt ein. Fertig.
Die Twain-Aufrufe must Du natürlich in Deine Anwendung einfügen, aber das sollte nicht das Problem sein.

Ich hätte schon was, womit Du mit eventuell helfen könntest.
Ich suche eine Klasse zum Faxen unter .NET. Schau mal unter http://www.java4less.com. Diese Fax-Klasse suche ich, aber ohne Bezahlung :)
Wenn Du was weist, oder hast, was dem ähnlich kommt, wäre das super.

Viel Erfolg,
Asterix

// Edit von Alex: Bitte unnötige Tabs entfernen, da die Zeilen sonst zu lange werden. Danke
 
Zuletzt bearbeitet von einem Moderator:
Hi Asterix,

erstmal tausend Dank.

Bin noch nicht dazugekommen, den Code auszuprobieren. Melde mich aber deswegen nochmal.
Ich mache mich in den nächsten Tagen auf die Suche nach einer Fax Klasse.
Ich glaube so etwas schon einmal kostenlos gesehen zu haben. In meinen vb.net Büchern steht so viel ich weiss auch etwas darüber drin.
Bitte noch etwas Geduld. Bei der Übersetzung in C# kann ich Dir natürlich nicht weiter helfen. Aber so wie ich Dich einschätze, machst Du das auch noch nach ner Kiste Bier.

Bis die Tage
Roman Brunetti
 
Zurück