【问题标题】:Problems converting image to bytes and then to string将图像转换为字节然后转换为字符串的问题
【发布时间】:2015-01-14 11:34:57
【问题描述】:

我有一个基于套接字通信的应用程序,服务器向客户端发送签名图像请求。签名在客户端获取并发送回服务器。

为此,我使用了一个图片框,将其数据转换为字节,然后转换为字符串以通过套接字连接发送到服务器。这一切正常。

我在保存数据库中收到的数据时遇到问题,因为我需要能够将其保存为图像类型,但此时数据仍然是字符串,所以我收到错误:

“操作数类型冲突:nvarchar 与图像不兼容”

我想这是因为我试图将字符串发送到 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);

【问题讨论】:

  • 所以将其转换回服务器上的图像,然后将其存储在数据库中
  • 首先,请在发帖时花些时间来格式化您的代码。第一个 sn-p 的大部分内容都向右缩进 方式。我现在已经修好了,但以后请多加注意。
  • @CoderofCode 这是我遇到的问题的一部分,我不确定如何将字符串转换回图像。

标签: c# .net image winforms sockets


【解决方案1】:

为此,我使用了一个图片框,将其数据转换为字节,然后转换为字符串以通过套接字连接发送到服务器。这一切正常。

鉴于您显示的代码,我建议它可能不会。特别是:

_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);

图像数据不是 UTF-8 编码的文本,因此您不应该使用Encoding.UTF8 或任何编码。编码旨在将自然纯文本转换为字节并返回。相反,您有任意二进制数据。

理想情况下,您应该通过套接字as 二进制数据来传输它——目前还不清楚为什么您需要一个字符串。如果你真的确实需要一个字符串,你应该使用 base64 将字节转换为文本:

string base64 = Convert.ToBase64String(bytes);

然后在另一边,你可以做相反的事情:

byte[] bytes = Convert.FromBase64String(base64);

但正如我所说,如果您可以控制协议,那么仅以二进制形式传输字节而不将它们转换为文本会更清洁、更有效。我们不知道这是什么协议,所以很难知道这是否是一个选项。

【讨论】:

    【解决方案2】:

    这个:

    _Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
    

    错了。 _imagevalues 是否保存图像的二进制数据? 比在您试图将其解释为字符串的那行代码中, 这是错误的。您只需转换每个单独的字节 的图像说它的十六进制字符串表示。然后通过网络发送整个这样的字符串。 例如,请参阅此处How do you convert Byte Array to Hexadecimal String, and vice versa?(如其中一个答案中所述,此转换 不是真的必要,你也可以发送纯字节)。

    然后在服务器端,你必须解析这个十六进制 字符串并将其转换为字节数组并可能保存在数据库中。

    【讨论】:

    • 这看起来很有希望,但是我在每次不同签名后返回的数据总是相同的,并且图像看起来像丢失的图像徽标。是因为我使用的是 PictureBox.InitialImage 吗?我尝试使用 .Image 但它始终为 NULL
    • @connersz:我不确定我明白你的意思。我只是建议跟随。假设您有二进制数据:123 22(2 个字节)。我告诉你如何将它编码为(并返回)十六进制字符串,例如“7B 16”。因此,如果您按照我告诉您的操作,在服务器端您应该收到字符串“7B 16”-> 然后您应该再次将其转换为字节数组 (123 22)。现在,你如何读取图像和字节数组,我不确定这取决于你。
    • 我的意思是当我从 .net PictureBox 控件中获取字节时,如果我尝试从 .Image 中获取图像,则它为 NULL。我需要提前调用一个方法来更新 .Image 吗?
    • @conners:这张图片是从文件中加载的吗?为什么不在那个文件上做ReadAllBytes
    • 不,它是使用签名板创建的,用户在其中写下他们的签名,所以就像需要先以某种方式关闭图像。
    猜你喜欢
    • 2019-10-10
    • 2017-04-14
    • 1970-01-01
    • 2021-11-21
    • 2019-10-16
    • 2014-01-04
    • 2011-12-18
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多