Problems converting image to bytes and then to string

I have a socket communication based application and the server sends a request to a client for a signature image. The signature is taken at the client and sent back to the server.

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.

I am having problems saving the data received in the database because I need to be able to save it as an image type but at this point the data is still a string so I am getting the error:

"Operand type clash: nvarchar is incompatible with image"

I presume it's because I am trying to send a string to a sql image type?

Code which attempts to call the procedure and errors (server end- received data as string):

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

}

Stored Procedure:

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

Converting the image into bytes:

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;

}

Converting the bytes to string (to send over socket):

_Reading = System.Text.Encoding.UTF8.GetString(_imagevalues);
Jon Skeet
people
quotationmark

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.

Given the code you've shown, I'd suggest it probably doesn't. In particular:

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

Image data is not UTF-8-encoded text, so you shouldn't be using Encoding.UTF8 or indeed any encoding. Encodings are designed to convert natural plain text into bytes and back. Instead, you have arbitrary binary data.

Ideally, you should transmit this over the socket as binary data - it's not clear why you need a string at all. If you really do need a string though, you should convert the bytes into text using base64:

string base64 = Convert.ToBase64String(bytes);

then on the other side, you can do the reverse:

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

But as I say, if you're in control of the protocol, it would be cleaner and more efficient to just transmit the bytes in binary form without converting them to text at all. We can't tell what protocol this is, so it's hard to know whether or not that's an option.

people

See more on this question at Stackoverflow