C# 图像中的转换字节数组返回无效参数异常

C# 图像中的转换字节数组返回无效参数异常,c#,C#,我有一个Java系统在我的系统中注册指纹。在我的数据库中,我们保存了指纹的字节数组 一段注册指纹的Java代码 enrollStmt = con.prepareStatement("INSERT INTO EnrollDigital (template, Client_Id) VALUES (?, ?)"); public void enroll(String clientID) { enrollStmt.setBinaryStream(1, new ByteArr

我有一个Java系统在我的系统中注册指纹。在我的数据库中,我们保存了指纹的字节数组

一段注册指纹的Java代码

       enrollStmt = con.prepareStatement("INSERT INTO EnrollDigital (template, Client_Id) VALUES (?, ?)");

public void enroll(String clientID) {
       enrollStmt.setBinaryStream(1, new ByteArrayInputStream(template.getData()),  template.getData().length);
       enrollStmt.setString(2, clientID);
       enrollStmt.executeUpdate();
}
现在我需要做相反的事情。由于字节数组thar保存在我的数据库中,我需要获取这些数据,并返回一个图像

我试着用这个C代码做这个

但它返回一个
无效参数异常
。我在Stackoverflow上看到了一些帖子,但没有成功

有人能帮我把保存在数据库中的字节数组转换成图像吗?我需要恢复指纹图像

表格结构

CREATE TABLE [dbo].[EnrollDigital](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [template] [varbinary](1000) NULL,
    [template2] [varbinary](1000) NULL,
    [template3] [varbinary](1000) NULL,
    [Client_Id] [int] NULL)

ID  Template 
4   0xA7FF011DCB00FD00013B01DA00E400023601A700FD00013B01A600EF00018D00D3001901018200C40043010282008E00C800024701A500B200018700D0004501013601E5000801018200B100B400013B016A00370101930063002E0102580194005E010130016E00E000029E0068000E01024C0198005001027C00C9007301027100D1006C01022B01B8007B01011F017B009501026B00680060010177005C004A01020C0048005F010144008600BC01021F01DC00B80101300158005801015A006F00C301011F016C00A901016B009D000B0C11120A07080502031A160D10171A151A1311160B1B1815161C1404091B1C0900171604000001160C13120C0F15170607181C00021A0B0901120800030E06060A18140B0F150B12051A0C150D080405040F0E10050306130D11081B141105150C15100402170B100B0301040113100D051415170C02010D0B1008110D1305030E130802060D16030A0D1A140D10161110160F03070403010A0902100C120D1210020E1A100F020D0808091413090305090D0C0F03141A050019130E070800191101071C15020A1417141002071A0F170D05021912000A0C0E0F060E0A1004171001060006100F1C1718131C1A120408021002000713150B020C021C0D14111819170F0B0E1C13180D000E1815090A1B151811120919141B131B1709071B0D1B1A1B1911091817191C190D1908150219051302170E17021909    0xA7FF011E8C00D700014400A600E900014F00C0001301026B00C8009300015801A7001601015A0091001501025A00C8008300025201CD001C01026B00CB002C01021F016D00A4000239004900BF0001F800A6004301016000DC00270102710060001F01014F000D01D600017C004300C500024400C3004C01026B0065007600012D001E01CF00013601BE00570001AF0010018300013B011A01A200018700F9002B01017700DF004300015801C500C700026301D200C100024701C500E700016000BA00EC00015A008500250102550093005301015500AA000F0A1B1A18190807070203060E12080C0C071B011C05040504021D0B0802160C100B011A01001A18151410080C021C041C0D0704021B13171B181A1908040B08021A0B1C061304010B04100C12150A09041B0816011816070911190305021D1C1B19100702011D1005010D050B051B00071B18030F09071A0E150B070B02041A0C041002051B00181A00011900090705100403130B0C16021D05050008051C02190610160E191D04081B0C1A061718061C011D080400081A081C000A06140D041D0D00190E1803141A0E000F0218121912141C000A111D0219150B0D14170E14150303171A030D00160404180F111B0E161A0B16160E191415060D01121801090719000301031A1214130903181505181113070E18090D0F0C0E0E0309060D0A16120611010A000603111B120011010F080E19131A150C12050A151709131813050F1C0F1C0A18111917111718170A0616150914  
更新

我按照一些指示在,我得到了以下方法

    internal static void BytesToBitmap(byte[] ptrNativeImage, Size imageSize, int resolution, out Bitmap ptrBitmapData)
    {
        const PixelFormat pxFormat = PixelFormat.Format8bppIndexed;

        ptrBitmapData = new Bitmap(imageSize.Width, imageSize.Height);
        ptrBitmapData.SetResolution(resolution, resolution);


        // Method #2
        BitmapData mapData = null;

        try
        {
            mapData = ptrBitmapData.LockBits(new Rectangle(Point.Empty, ptrBitmapData.Size),
                ImageLockMode.WriteOnly, pxFormat);

            //[https://stackoverflow.com/questions/1983781/why-does-bitmapsource-create-throw-an-argumentexception/1983886#1983886][3]
            int bitsPerPixel = ((int)pxFormat >> 8) & 0xFF;

            //Number of bits used to store the image data per line (only the valid data)
            int validBitsPerLine = imageSize.Width * bitsPerPixel;

            //4 bytes for every int32 (32 bits)
            int stride = ((validBitsPerLine + 31) / 32) * 4;
            mapData.Stride = stride;

            Marshal.Copy(ptrNativeImage, 0, mapData.Scan0, ptrNativeImage.Length);
        }
        finally
        {                
            if (mapData != null)
                ptrBitmapData.UnlockBits(mapData);
        }
    }
我把这个方法叫做

Size s = new System.Drawing.Size();
s.Height = 750;
s.Width = 750;
try
{
     Bitmap bmp = new Bitmap(10, 10);
     BytesToBitmap(templateData, s, 10, out bmp);
     bmp.Save("F:\\img.bmp");
}
catch (System.Exception e)
{
}            

但是它会保存一个黑色图像。

当使用
varbinary
数据类型将二进制数据保存到sql server时,
SqlDataReader
或类似的类已经知道如何获取字节数组

无需将varbinary转换为字符串

您应该使用这样的代码:

        using (SqlCommand cmd = new SqlCommand("select template from dbo.EnrollDigital where id=4", sqlConnection))
        {
            byte[] templateData = (byte[])cmd.ExecuteScalar();
            Image img = byteArrayToImage(templateData);
        }

为什么不让Bitmap类为您加载图像:

byte[] templateData = .... // get bytes from db.
Bitmap bm = new Bitmap(new MemoryStream(templateData));

位图(从图像继承)将读取图像标题并确定如何加载它。

byteArrayToImage返回
void
,但您尝试返回
图像。错别字?对不起,这是因为我试过在stackoverflow上看到的一些代码。但是该方法返回Image。首先,byteArrayIn可能为null。如果流不工作,您可能需要ms.读取流。您如何调用
byteArrayToImage
函数?@NirKornfeld我用完整的代码更新了我的C代码。是否可能保存图像的代码使用了与读取图像的代码不同的格式?也许你应该试着写一个保存图像的C#代码并进行测试。指纹读取器的制造商告诉我,图像是BMP,8位。我得到了一些关于这个问题的消息,我有一种将字节转换为位图的方法,就像你在我的更新中看到的那样,我想这是今早以来我得到的最接近的一张。如果我把750x750放在我的尺寸上,它会保存一张黑色图像。指纹设备保存的源图像是750x750吗?如果二进制数据流是一个完整的BMP文件,那么它应该包含所有元数据。无需在代码中指定分辨率和所有其他参数。你能和设备制造商核实一下吗?因为这样会返回
无效参数异常
确定-那么我猜图像是无效的。你能把图像提取到一个文件中,然后像那样打开它吗?给它一个bmp扩展名。在十六进制编辑器中将其与已知有效的8位bmp进行比较,或查看标题规范:。我只想把它和另一个有效的bmp进行比较,如果我能告诉你——至少从一开始。
byte[] templateData = .... // get bytes from db.
Bitmap bm = new Bitmap(new MemoryStream(templateData));