How to convert object in byte[] c# - c#

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

How to retrieve byte array to image c#

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();
}
}

PDDocument addPage /importPage not working correct

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.

Sending an Image from the Client to the Server

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

Memorystream object being passed to method doesn't contain values

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.

how to show two object in an control how i can put each object in separeate column

_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;
}

Categories