将图像转换为字节然后再转换为字符串的问题
Problems converting image to bytes and then to string
我有一个基于套接字通信的应用程序,服务器向客户端发送签名图像请求。签名在客户端获取并发送回服务器。
为此,我使用了一个图片框,它的数据被转换为字节,然后转换为字符串,通过套接字连接发送到服务器。一切正常。
我在保存数据库中收到的数据时遇到问题,因为我需要能够将其保存为图像类型,但此时数据仍然是一个字符串,所以我收到错误消息:
"Operand type clash: nvarchar is incompatible with image"
我想这是因为我正在尝试将字符串发送到 sql 图像类型?
尝试调用过程和错误的代码(服务器端接收的数据为字符串):
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["GetConnector"].ConnectionString))
{
SqlCommand sqlComm = new SqlCommand("PL_Device_ReadData", conn);
sqlComm.Parameters.AddWithValue("@DeviceTypeID", DeviceID);
sqlComm.Parameters.AddWithValue("@RequestID", RequestID);
if (DeviceID != "5")
{
sqlComm.Parameters.AddWithValue("@Reading", Reading);
}
else if (DeviceID == "5")
{
sqlComm.Parameters.AddWithValue("@ImageReading", Reading);
sqlComm.Parameters.Add("@ImageReading", SqlDbType.Image);
sqlComm.Parameters["@ImageReading"].Value = Reading;
}
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
}
catch (Exception e)
{
}
存储过程:
ALTER PROCEDURE [dbo].[PL_Device_ReadData]
@DeviceTypeID INT,
@RequestID INT,
@Reading NVARCHAR(100) = NULL,
@ImageReading IMAGE = NULL
AS
BEGIN
--Data
IF @DeviceTypeID = 5
BEGIN
UPDATE dbo.DeviceRequests
SET ImageData = @ImageReading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
ELSE
BEGIN
UPDATE dbo.DeviceRequests
SET Value = @Reading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
END
正在将图像转换为字节:
byte[] imgData = null;
// storage for the img bytes
imgData = ImgToByteArray(picSignature.InitialImage, ImageFormat.Jpeg);
public static byte[] ImgToByteArray(Image img, ImageFormat imgFormat)
{
byte[] tmpData = null;
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, imgFormat);
tmpData = ms.ToArray();
}
// dispose of memstream
return tmpData;
}
将字节转换为字符串(通过套接字发送):
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
To do this I have used a picture box, who's data is converted into bytes and then into a string to send over the socket connection to the server. This all works OK.
鉴于您显示的代码,我认为它可能不会。特别是:
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
图像数据是 而非 UTF-8 编码文本,因此您不应使用 Encoding.UTF8
或任何编码。编码旨在将自然纯文本转换为字节并返回。相反,你有任意二进制数据。
理想情况下,您应该通过套接字将其作为 二进制数据传输——目前还不清楚为什么您需要一个字符串。如果你真的 do 需要一个字符串,你应该使用 base64:
将字节转换为文本
string base64 = Convert.ToBase64String(bytes);
然后在另一边,你可以做相反的事情:
byte[] bytes = Convert.FromBase64String(base64);
但正如我所说,如果您能控制协议,那么以二进制形式传输字节而不将它们转换为文本会更干净、更高效。我们不知道这是什么协议,所以很难知道这是否是一个选项。
这个:
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
错了。 _imagevalues
是否保存图像的二进制数据?
比起你试图将其解释为字符串的那行代码,
这是错误的。您只需转换每个单独的字节
图像的十六进制字符串表示形式。然后通过网络发送整个这样的字符串。
例如,请参阅此处 How do you convert Byte Array to Hexadecimal String, and vice versa?(如其中一个答案所述,此转换
并不是真的有必要,您也可以发送纯字节)。
然后在服务器端,你要解析这个十六进制
字符串并将其转换为字节数组并可能保存在数据库中。
我有一个基于套接字通信的应用程序,服务器向客户端发送签名图像请求。签名在客户端获取并发送回服务器。
为此,我使用了一个图片框,它的数据被转换为字节,然后转换为字符串,通过套接字连接发送到服务器。一切正常。
我在保存数据库中收到的数据时遇到问题,因为我需要能够将其保存为图像类型,但此时数据仍然是一个字符串,所以我收到错误消息:
"Operand type clash: nvarchar is incompatible with image"
我想这是因为我正在尝试将字符串发送到 sql 图像类型?
尝试调用过程和错误的代码(服务器端接收的数据为字符串):
try
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["GetConnector"].ConnectionString))
{
SqlCommand sqlComm = new SqlCommand("PL_Device_ReadData", conn);
sqlComm.Parameters.AddWithValue("@DeviceTypeID", DeviceID);
sqlComm.Parameters.AddWithValue("@RequestID", RequestID);
if (DeviceID != "5")
{
sqlComm.Parameters.AddWithValue("@Reading", Reading);
}
else if (DeviceID == "5")
{
sqlComm.Parameters.AddWithValue("@ImageReading", Reading);
sqlComm.Parameters.Add("@ImageReading", SqlDbType.Image);
sqlComm.Parameters["@ImageReading"].Value = Reading;
}
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
}
catch (Exception e)
{
}
存储过程:
ALTER PROCEDURE [dbo].[PL_Device_ReadData]
@DeviceTypeID INT,
@RequestID INT,
@Reading NVARCHAR(100) = NULL,
@ImageReading IMAGE = NULL
AS
BEGIN
--Data
IF @DeviceTypeID = 5
BEGIN
UPDATE dbo.DeviceRequests
SET ImageData = @ImageReading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
ELSE
BEGIN
UPDATE dbo.DeviceRequests
SET Value = @Reading
WHERE id = @RequestID
AND DeviceTypeID = @DeviceTypeID
END
END
正在将图像转换为字节:
byte[] imgData = null;
// storage for the img bytes
imgData = ImgToByteArray(picSignature.InitialImage, ImageFormat.Jpeg);
public static byte[] ImgToByteArray(Image img, ImageFormat imgFormat)
{
byte[] tmpData = null;
using (MemoryStream ms = new MemoryStream())
{
img.Save(ms, imgFormat);
tmpData = ms.ToArray();
}
// dispose of memstream
return tmpData;
}
将字节转换为字符串(通过套接字发送):
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
To do this I have used a picture box, who's data is converted into bytes and then into a string to send over the socket connection to the server. This all works OK.
鉴于您显示的代码,我认为它可能不会。特别是:
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
图像数据是 而非 UTF-8 编码文本,因此您不应使用 Encoding.UTF8
或任何编码。编码旨在将自然纯文本转换为字节并返回。相反,你有任意二进制数据。
理想情况下,您应该通过套接字将其作为 二进制数据传输——目前还不清楚为什么您需要一个字符串。如果你真的 do 需要一个字符串,你应该使用 base64:
将字节转换为文本string base64 = Convert.ToBase64String(bytes);
然后在另一边,你可以做相反的事情:
byte[] bytes = Convert.FromBase64String(base64);
但正如我所说,如果您能控制协议,那么以二进制形式传输字节而不将它们转换为文本会更干净、更高效。我们不知道这是什么协议,所以很难知道这是否是一个选项。
这个:
_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
错了。 _imagevalues
是否保存图像的二进制数据?
比起你试图将其解释为字符串的那行代码,
这是错误的。您只需转换每个单独的字节
图像的十六进制字符串表示形式。然后通过网络发送整个这样的字符串。
例如,请参阅此处 How do you convert Byte Array to Hexadecimal String, and vice versa?(如其中一个答案所述,此转换
并不是真的有必要,您也可以发送纯字节)。
然后在服务器端,你要解析这个十六进制 字符串并将其转换为字节数组并可能保存在数据库中。