0

我有一个 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# 代码做到这一点

public Form1()
{
     InitializeComponent();
     Image img = byteArrayToImage(GetBytes("my_array_that_was_saved_in_my_database"));                
}

public Image byteArrayToImage(byte[] byteArrayIn)
{
     MemoryStream ms = new MemoryStream(byteArrayIn);
     Image returnImage = Image.FromStream(ms);
     return returnImage;
}

static byte[] GetBytes(string str)
{
     byte[] bytes = new byte[str.Length * sizeof(char)];
     System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
     return bytes;
}

但它返回一个Invalid Argument Exception. 我在 Stackoverflow 中看到了一些类似这样的帖子,但没有成功。

有人可以帮我将保存在我的数据库中的字节数组转换为 Image 吗?我需要恢复指纹图像。

表结构

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  

更新

我在 StackOverflow上的这篇文章中遵循了一些说明,并得到了以下方法。

    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)
{
}            

但它会保存黑色图像。

4

2 回答 2

1

使用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);
        }
于 2013-09-09T14:28:33.107 回答
0

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

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

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

于 2013-09-09T20:11:02.503 回答