CONVERT OBJECT TO BYTE[]
Hello how are you? I'm having difficulties in converting an object (returned by a query to the Postgres database) to byte[], I test in several different ways but I can't get the total size of the array stored in the database referring to the image. I have a single image saved in the database, and in each way I try to retrieve it, the byte[] comes with a different size depending on how I do the conversion from object to byte[]. The biggest array size I got was length = 42, the image has length = 675486. I've tried these ways.
using (conexao)
{
string sQL = " SELECT p.photo_img " +
" FROM empresa as e, photo as p " +
" WHERE e.empresa_img = " + id + " AND " +
" e.empresa_img = p.photo_id; ";
using (var command = new NpgsqlCommand(sQL, conexao))
{
byte[] productImageByte = null;
conexao.Open();
var rdr = command.ExecuteReader();
while (rdr.Read())
{
productImageByte = (byte[])rdr[0];
}
rdr.Close();
if (productImageByte != null)
{
using (MemoryStream productImageStream = new MemoryStream(productImageByte))
{
ImageConverter imageConverter = new System.Drawing.ImageConverter();
pct_Imagem.Image = imageConverter.ConvertFrom(productImageByte) as System.Drawing.Image;
}
}
}
}
The result of this was length = 13
private void dgv_empresa_CellClick(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32(dgv_empresa.SelectedCells[0].OwningRow.Cells[9].Value);
if (id != 0)
{
try
{
string query = " SELECT p.photo_img " +
" FROM empresa as e, photo as p " +
" WHERE e.empresa_img = " + id + " AND " +
" e.empresa_img = p.photo_id; ";
conexao.Open();
DataTable dados = new DataTable();
NpgsqlDataAdapter adaptador = new NpgsqlDataAdapter(query, conexao);
adaptador.Fill(dados);
if (dados.Rows.Count > 0)
{
foreach (DataRow linha in dados.Rows)
{
byte[] data = ObjectToByteArray(linha[0]);
var imagem = (Image)new ImageConverter().ConvertFrom(data);
pct_Imagem.Image = imagem;
}
}
}
catch (Exception ex)
{
conexao.Close();
MessageBox.Show(ex.Message, "Erro no Banco de Dados!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
conexao.Close();
}
}
}
byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
The result of this was length = 42
These last two brought me the best results. But still, it's not a valid byte array. Can someone help me?
you can use this method that I serialized the class into JSON text and then converted it to byte[]. You can either serialize it to XML
private byte[] CreateByteArray(object obj)
{
using var memoryStream = new MemoryStream();
using var writer = new StreamWriter(memoryStream);
var jsonText = JsonConvert.SerializeObject(obj);
writer.WriteAsync(jsonText);
writer.Flush();
return memoryStream.ToArray();
}
I managed to do, what I needed to adjust to not use Connetion, but create and discard in each block that was to be used
Related
I'm trying to retrieve an image saved in postgresql database in BYTEA format, but I'm having difficulties in transforming the byte array to image using C#. I'm getting "INVALID PARAMETERS" as a return. I've been trying for days and still haven't been able to. Can anyone help me?
byte[] ObjectToByteArray(object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
bf.Serialize(ms, obj);
return ms.ToArray();
}
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
try
{
using (MemoryStream mStream = new MemoryStream(byteArrayIn))
{
return Image.FromStream(mStream);
}
}
catch (Exception)
{
throw;
}
}
private void dgv_empresa_CellClick(object sender, DataGridViewCellEventArgs e)
{
int id = Convert.ToInt32(dgv_empresa.SelectedCells[0].OwningRow.Cells[9].Value);
if (id != 0)
{
try
{
string query = " SELECT p.photo_img " +
" FROM empresa as e, photo as p " +
" WHERE e.empresa_img = " + id + " AND " +
" e.empresa_img = p.photo_id; ";
conexao.Open();
dgv_empresa.Rows.Clear();
DataTable dados = new DataTable();
NpgsqlDataAdapter adaptador = new NpgsqlDataAdapter(query, conexao);
adaptador.Fill(dados);
Image imagem = null;
if (dados.Rows.Count > 0)
{
foreach (DataRow linha in dados.Rows)
{
byte[] binary = ObjectToByteArray(linha[0]);
MemoryStream ms = new MemoryStream(binary, 0, binary.Length);
ms.Position = 0;
imagem = Image.FromStream(ms, true);
Image i = byteArrayToImage(binary);
}
}
pct_Imagem.Image = imagem;
}
catch (Exception ex)
{
conexao.Close();
MessageBox.Show(ex.Message, "Erro no Banco de Dados!", MessageBoxButtons.OK, MessageBoxIcon.Error);
//dgv_empresa.Rows.Clear();
}
finally
{
conexao.Close();
}
}
I am using PDFBox 1.8.3 and my need is to take a set of ZPLs and convert them all into one PDF. For the conversion part(ZPL to PDF), we are using labelary and this works correctly. I am basically using PDFBox to "stitch" all these individual PDFs. My source code is very simple as below :
var outputByteStream = new ByteArrayOutputStream();
var destinationDoc = null;
var doc = null;
for each(var img in images.toArray()) {
log.debug("Working with image : " + img);
if("ZPL".equalsIgnoreCase(img.getFormat()) || "ZPL203".equalsIgnoreCase(img.getFormat())) {
try {
var convertorServiceUrl = "http://labelary ...." + img.getId()+"?labelSize=4x6&density=8dpmm";
var urlObject = new URL(convertorServiceUrl);
var conn = urlObject.openConnection();
conn.connect();
if(destinationDoc == null ) {
var tmpfile = java.io.File.createTempFile(pw +"-"+uniqKey, ".pdf");
var raf = new org.apache.pdfbox.io.RandomAccessFile(tmpfile, "rw");
destinationDoc = PDDocument.load(conn.getInputStream(), raf);
}
else {
doc = PDDocument.load(conn.getInputStream());
if (doc != null && doc.getNumberOfPages() > 0) {
var page = doc.getDocumentCatalog().getAllPages().get(0);
destinationDoc.importPage(page);
}
}
} catch (res) {
log.error("Error message retrieved is " + exceptionMsg);
throw new BaseRuntimeException("Unable to convert the PDF for image with id " + img.getId(), res);
}
}
}
try {
if(destinationDoc != null) {
destinationDoc.save(outputByteStream);
destinationDoc.close();
}
} catch (e1) {
log.error("Error in writing the document to the output stream " + pw + "." , e1);
throw e1;
}
return outputByteStream.toByteArray();
Source code runs and generates a PDF but all the pages of the PDF are pointing to the first page. So if my for-loop run 4 times, all 4 pages of the PDF are for first label.
If I use addPage like below
var outputByteStream = new ByteArrayOutputStream();
var destinationDoc = new PDDocument();
var doc = null;
for each(var img in images.toArray()) {
log.debug("Working with image : " + img);
if("ZPL".equalsIgnoreCase(img.getFormat()) || "ZPL203".equalsIgnoreCase(img.getFormat())) {
try {
var convertorServiceUrl = "http://labelary ...." + img.getId()+"?labelSize=4x6&density=8dpmm";
var urlObject = new URL(convertorServiceUrl);
var conn = urlObject.openConnection();
conn.connect();
doc = PDDocument.load(conn.getInputStream());
if (doc != null && doc.getNumberOfPages() > 0) {
var page = doc.getDocumentCatalog().getAllPages().get(0);
destinationDoc.addPage(page);
}
} catch (res) {
log.error("Error message retrieved is " + exceptionMsg);
throw new BaseRuntimeException("Unable to convert the PDF for image with id " + img.getId(), res);
}
}
}
try {
if(destinationDoc != null) {
destinationDoc.save(outputByteStream);
destinationDoc.close();
}
} catch (e1) {
log.error("Error in writing the document to the output stream " + pw + "." , e1);
throw e1;
}
return outputByteStream.toByteArray();
Then the result is a PDF page with all empty pages.
I have already ensured that the content returned from the labelary service is correct and if I simply take the response and save it into a file it works correctly. Even saving the PDDocument one page at a time also produces the PDF correctly.
The problem I have is with the "stitching" of PDFs. It should work as per the documentation but I am not sure what I am doing wrong.
So, I am trying to send an image between the server and client, however, somehow when the server receives the image, the image does not render all of it.
Client Side code:
//button click
Bitmap tImage = new Bitmap(#"C:\Users\Milan\Downloads\guitarstill.gif");
byte[] bStream;
//if (string.IsNullOrEmpty(tbPayload.Text)) return;
try
{
bStream = imageToByteArray(tImage);
if (mTcpClient != null)
{
if (mTcpClient.Client.Connected)
{
mTcpClient.GetStream().BeginWrite(imageToByteArray(tImage), 0, imageToByteArray(tImage).Length, onCompleteWriteToServer, mTcpClient);
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
//Within another method:
public byte[] imageToByteArray(System.Drawing.Image imageIn) {
MemoryStream ms = new MemoryStream();
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
//richTextBox1.Text = ms.ToArray().ToString();
return ms.ToArray();
}
Server Side Code:
void onCompleteReadFromTCPClientStream(IAsyncResult iar)
{
TcpClient tcpc;
int nCountReadBytes = 0;
string strRecv;
ClientNode cn = null;
try
{
lock (mlClientSocks)
{
tcpc = (TcpClient)iar.AsyncState;
cn = mlClientSocks.Find(x => x.strId == tcpc.Client.RemoteEndPoint.ToString());
nCountReadBytes = tcpc.GetStream().EndRead(iar);
if (nCountReadBytes == 0)// this happens when the client is disconnected
{
MessageBox.Show("Client disconnected.");
mlClientSocks.Remove(cn);
lbClients.Items.Remove(cn.ToString());
return;
}
strRecv = Encoding.ASCII.GetString(cn.Rx, 0, nCountReadBytes);
//strRecv = Encoding.ASCII.GetString(mRx, 0, nCountReadBytes);
if (strRecv.StartsWith("GIF"))
{
//MemoryStream ms = new MemoryStream(cn.Rx);
//Image x = (Bitmap)((new ImageConverter()).ConvertFrom(cn.Rx));
pictureBox1.Image = byteArrayToImage(cn.Rx);
/*
lock (mlClientSocks)
{
//if (cn != null && cn.tclient != null && cn.tclient.Client.Connected)
//{
//foreach (var clients in spectatorsIPAndPort)
//{
cn = mlClientSocks.Find(x => x.strId == clients);
cn.Tx = new byte[512];
cn.Tx = Encoding.ASCII.GetBytes(strRecv);
cn.tclient.GetStream().BeginWrite(cn.Tx, 0, cn.Tx.Length, onCompleteWriteToClientStream, cn.tclient);
//Console.WriteLine("Sent Number of Clients via Request: " + Encoding.UTF8.GetString(cn.Tx) + " To " + clients);
//}
//}
}
*/
//printLine(DateTime.Now + " - " + cn.ToString() + ": " + strRecv);
}
cn.Rx = new byte[512];
tcpc.GetStream().BeginRead(cn.Rx, 0, cn.Rx.Length, onCompleteReadFromTCPClientStream, tcpc);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
lock (mlClientSocks)
{
printLine("Client disconnected: " + cn.ToString());
mlClientSocks.Remove(cn);
lbClients.Items.Remove(cn.ToString());
}
}
}
//within another method
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn, 0, byteArrayIn.Length);
//ms.Position = 0;
Image returnImage = Image.FromStream(ms);
return returnImage;
}
My Output:
Expected output: - this full image
I am using a memorystream object to write values from streamwriter object into memory. I have several methods which are for logging errors and values so I pass my memorystream object between them as a parameter.
My problem is the memorystream doesn't contain values. See code below:
#region csvlogging
public static void initiateCsvLogging(SortedList<int, string> logList, SortedList<int, string> errorList) // Handles csv upload logging
{
logMsgError(errorList, logList);
}
public static void logMsgError(SortedList<int, string> errorList, SortedList<int, string> logList)
{
using (MemoryStream ms = new MemoryStream())
{
StreamWriter sw = new StreamWriter(ms);
try
{
sw.WriteLine("Errors:");
foreach (KeyValuePair<int, string> k in errorList)
{
if (k.Value == null)
{
sw.WriteLine("No errors reported.");
}
else
{
sw.WriteLine(k.Key + "," + k.Value);
}
}
}
catch (Exception ex)
{
}
finally
{
sw.WriteLine("");
}
logMsg(logList, ms);
}
} // Handles data upload error logging for csv
public static MemoryStream logMsg(SortedList<int, string> logList, MemoryStream ms)
{
string DateNow = System.DateTime.Now.Date.ToString("yyyy-MM-dd");
string FileName = "log " + DateNow + ".csv";
char[] delimiterChars = { ',' };
try
{
// Write values to textfile and save to Log folder
using (StreamWriter sw = new StreamWriter(ms))
{
if (logList.Keys.Count == 0)
{
sw.WriteLine("No new users added to Active Directory.");
}
else // If keys > 0 then new users have been added to AD
{
sw.WriteLine("Username" + "," + "Password" + "," + "Company" + "," + "Email");
foreach (KeyValuePair<int, string> k in logList)
{
string[] values = k.Value.Split(delimiterChars);
sw.WriteLine(values[0] + "," + values[1] + "," + values[2] + "," + values[3]);
}
}
try
{
sw.Flush();
sendLogByEmail(new MemoryStream(ms.ToArray()), FileName);
}
catch (Exception ex)
{
}
}
}
catch (ThreadAbortException ex)
{
}
finally
{
}
return ms;
} // Handles logging for csv
public static void sendLogByEmail(MemoryStream ms, string error, int count)
{
//Send mail by attachment code
SmtpClient smtpclient = new SmtpClient();
//smtpclient.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
//smtpclient.UseDefaultCredentials = true;
smtpclient.Host = "ldnmail";
MailMessage message = new MailMessage("nick.gowdy#orcinternational.co.uk", "nick.gowdy#orcinternational.co.uk");
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
attach.ContentDisposition.FileName = error;
message.Attachments.Add(attach);
smtpclient.Send(message);
}
#endregion
Because I am not using the USING keyword do I have to write some more code for the memorystream object?
You have to flush (Close) the StreamWriter.
finally
{
sw.WriteLine("");
}
sw.Flush();
logMsg(logList, ms);
But in the end you use all data to send it by mail:
System.Net.Mime.ContentType ct = new
System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Text.Plain);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(ms, ct);
It would seem a lot easier to collect the information in a StringBuilder through an attached StringWriter.
There are issues with a StreamWriter closing its Stream, that may be part of your problem.
_objbefor = Convertor.XmlDesrialize.XmlDesrializer.DesrializeAnyObject(_XmlObjBefor, _ObjectType);
_objAfter = Convertor.XmlDesrialize.XmlDesrializer.DesrializeAnyObject(_XmlObjAfter, _ObjectType);
//exteract properties of loged object
PropertyInfo[] _PropertyInfo = _ObjectType.GetProperties();
List<string> _ObjBeforTostring = new List<string>();
//_ObjBeforTostring.Add("");
_ObjBeforTostring.Add("*************Befor Object**********");
_ObjBeforTostring.Add("");
foreach (PropertyInfo pf in _PropertyInfo)
{
if (_objbefor != null)
{
string _str = pf.GetValue(_objbefor, null).ToString();
_ObjBeforTostring.Add(pf.Name.ToString() + " :: ( " + _str + " )");
_ObjBeforTostring.Add("==============================");
}
}
_ObjBeforTostring.Add("");
_ObjBeforTostring.Add("*************After Object**********");
_ObjBeforTostring.Add("");
foreach (PropertyInfo pf in _PropertyInfo)
{
if (_objAfter != null)
{
string _str = pf.GetValue(_objAfter, null).ToString();
_ObjBeforTostring.Add(pf.Name.ToString() + " :: ( " + _str+" )");
_ObjBeforTostring.Add("==============================");
}
}
I would do binary serialization:
public byte[] Serialize(object myObject)
{
MemoryStream stream = new MemoryStream()
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, myObject);
stream.Seek(0, SeekOrigin.Begin);
byte[] result = stream.ToArray();
stream.Close();
return result;
}