图像中的转换字节数组返回无效参数异常
本文关键字:返回 无效 参数 异常 数组 字节数 转换 字节 图像 | 更新日期: 2023-09-27 18:30:45
我有一个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中看到了一些像这样的帖子,但没有成功。
有人可以帮助我转换保存在图像数据库中的字节数组吗?我需要恢复指纹图像。
表结构
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)
{
}
但它保存了一个黑色图像。
当使用varbinary
数据类型将二进制数据保存到sql server时,SqlDataReader
或类似的类已经知道如何获取字节数组。
无需将变量二进制转换为字符串...
您应该使用这样的代码:
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));
位图(继承自图像)将读取图像标题并弄清楚如何加载它。