Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WindowsForm PictureBox.Image is null even though there's an image shown in the form

I'm trying to capture the finger print scanned by this device-> http://www.nitgen.com/eng/product/finkey.html

I'm able to scan the fingerprint and save the binary data successfully. I'm also able to display the fingerprint in the picture box. However when I'm trying to save the fingerprint displayed in the picture box, I'm getting an error that the Image of the picturebox is null.

Below is my code of capturing the fingerprint and saving the image from the picturebox.

public class Form1 : System.Windows.Forms.Form
{
    public NBioBSPCOMLib.NBioBSP objNBioBSP;
    public NBioBSPCOMLib.IExtraction objExtraction;
    private PictureBox pictureExtWnd;

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Create NBioBSP object
        objNBioBSP = new NBioBSPCOMLib.NBioBSPClass();
        objExtraction = (NBioBSPCOMLib.IExtraction)objNBioBSP.Extraction;
        pictureExtWnd.Image = new Bitmap(pictureExtWnd.Width, pictureExtWnd.Height);
    }

    private void buttonEnroll_Click(object sender, System.EventArgs e)
    {
        //tell NBIO to not display their fingerprint scanning window
        objExtraction.WindowStyle = NBioBSPType.WINDOW_STYLE.INVISIBLE;

        //set the color of the fingerprint captured
        objExtraction.FPForeColor = "000000";

        //set the color of the background where the fingerprint will be displayed
        objExtraction.FPBackColor = "FFFFFF";

        //tell NBIO that the scanned fingerprint will be displayed in the picturebox
        //by giving the handle control to NBIO
        objExtraction.FingerWnd = pictureExtWnd.Handle.ToInt32();

        //start scanning the fingerprint. This is also where the fingerprint
        //is displayed in the picturebox. 
        objExtraction.Capture((int)NBioBSPType.FIR_PURPOSE.VERIFY);

        //if there's no problem while scanning the fingerprint, save the fingerprint image
        if (objExtraction.ErrorCode == NBioBSPError.NONE)
        {
            string fileName = RandomString.GetRandomString(16, true) + ".bmp";

            using (SaveFileDialog sfdlg = new SaveFileDialog())
            {
                sfdlg.Title = "Save Dialog";
                sfdlg.Filter = "Bitmap Images (*.bmp)|*.bmp|All files(*.*)|*.*";
                if (sfdlg.ShowDialog(this) == DialogResult.OK)
                {
                    pictureExtWnd.Image.Save(sfdlg.FileName, ImageFormat.Bmp);
                    MessageBox.Show("FingerPrint Saved Successfully.");
                }
            }
        }
        else
        {
            MessageBox.Show("FingerPrint Saving Failed!");
        }
    }
}

I've tried enclosing inside

using(Graphics g = new Graphics)
{
    objExtraction.Capture((int)NBioBSPType.FIR_PURPOSE.VERIFY);
} 

since I've read that when doing edits on an image, you need to use graphics. but nothing is happening obviously since the api isn't using the graphic object I instantiated.

UPDATE: This is what I ended up doing:

using (SaveFileDialog sfdlg = new SaveFileDialog())
        {
            sfdlg.Title = "Save Dialog";
            sfdlg.Filter = "Bitmap Images (*.bmp)|*.bmp|All files(*.*)|*.*";
            if (sfdlg.ShowDialog(this) == DialogResult.OK)
            {
                Graphics gfx = this.pictureExtWnd.CreateGraphics();
                Bitmap bmp = new Bitmap(this.pictureExtWnd.Width, this.pictureExtWnd.Height);
                this.pictureExtWnd.DrawToBitmap(bmp, new Rectangle(0, 0, this.pictureExtWnd.Width, this.pictureExtWnd.Height));
                bmp.Save(sfdlg.FileName, ImageFormat.Bmp);

                gfx.Dispose();
                //pictureExtWnd.Image.Save(sfdlg.FileName, ImageFormat.Bmp);
                MessageBox.Show("Saved Successfully...");
            }
        }
like image 741
Jemuel Dalino Avatar asked Oct 05 '22 10:10

Jemuel Dalino


1 Answers

    objExtraction.FingerWnd = pictureExtWnd.Handle.ToInt32();

You passed the window handle to the fingerprint scanner. That's a common way to tell a chunk of native code about a window that it can draw to. It will typically sub-class the window procedure to respond to WM_PAINT requests, for example, same idea as NativeWindow.WndProc().

Implied however is that the Image property is useless. That native code has no idea that this is a PictureBox control and that it has an Image property. It only knows about the native window that was created for the control.

Do look in the api for an option to save the image, this ought to be available. If not then your first shot at saving it is using the picture box' DrawToBitmap() method. Which may work if the scanner implements the WM_PRINT message handler. If that doesn't work then your only other backup plan is to use Graphics.CopyFromScreen(). Which will always work, as long as the window is in the foreground. Similar to using the PrtSc button on your keyboard, a screen-shot.

like image 72
Hans Passant Avatar answered Oct 10 '22 03:10

Hans Passant