AFAIK você não pode recuperar um byte[] usando ExecuteScalar. Você deve usar ExecuteReader em vez disso. Apenas para estar no lado seguro ao inserir parâmetros, prefiro especificar os tipos, então minha inserção fica assim:
using (var conn = new NpgsqlConnection(connString))
{
string sQL = "insert into picturetable (id, photo) VALUES(65, @Image)";
using (var command = new NpgsqlCommand(sQL, conn))
{
NpgsqlParameter param = command.CreateParameter();
param.ParameterName = "@Image";
param.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bytea;
param.Value = ImgByteA;
command.Parameters.Add(param);
conn.Open();
command.ExecuteNonQuery();
}
}
Eu posso então recuperar e carregar a imagem assim:
using (var conn = new NpgsqlConnection(connString))
{
string sQL = "SELECT photo from picturetable WHERE id = 65";
using (var command = new NpgsqlCommand(sQL, conn))
{
byte[] productImageByte = null;
conn.Open();
var rdr = command.ExecuteReader();
if (rdr.Read())
{
productImageByte = (byte[])rdr[0];
}
rdr.Close();
if (productImageByte != null)
{
using (MemoryStream productImageStream = new System.IO.MemoryStream(productImageByte))
{
ImageConverter imageConverter = new System.Drawing.ImageConverter();
pictureBox1.Image = imageConverter.ConvertFrom(productImageByte) as System.Drawing.Image;
}
}
}
}
Eu não sei se especificar o tipo de dados na inserção faz alguma diferença, então tente apenas recuperar usando um Reader primeiro. Se isso não funcionar, sugiro alterar sua rotina de inserção para algo parecido com o meu.
Observe que no meu exemplo id é um número inteiro, não um caractere variando!