Create a VSTO shape from byte array - c#

I have an image that is encoded in a byte array and I would like to add it as a shape in an excel document but unfortunetly the only available function I see to do this requires me to save the image to the drive and then read it. As you see this is a really slow operation and I would like to simply read the image from the byte stream and decode it into a bitmap.
I have encoded it like this :
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.QualityLevel = 100;
byte[] bit = null;
using (var ms = new MemoryStream())
{
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(ms);
bit = ms.ToArray();
}
Now, how to add it to the worksheet ?
The method Shapes.AddPicture accepts only a filename and cannot read from a stream.

The Excel object model doesn't provide any method for reading a byte array and then add it as a shape. So, the only possible solution is to save the byte array as a file on the disk and then add it as a shape as you stated earlier:
to save the image to the drive and then read it.

Related

Convert PDF to Image Byte array to save to database

What I am trying to accomplish is allowing my user to upload a PDF. I will then convert that to an Image and get the Images byte array. Below is what I have so far.
PdfDocumentProcessor pdfDocumentProcessor = new PdfDocumentProcessor();
using (MemoryStream ms = new MemoryStream(e.UploadedFile.FileBytes))
{
pdfDocumentProcessor.LoadDocument(ms);
for (int i = 1; i <= pdfDocumentProcessor.Document.Pages.Count; i++)
{
Bitmap image = pdfDocumentProcessor.CreateBitmap(i, 1000);
try
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
}
catch (Exception error)
{
string message = error.Message;
}
}
When I try to save the Image to the memory stream I am getting the error "A generic error occurred in GDI+" I believe this has something to do with me not specifying a path for the image to be saved to, but I could be mistaken.
I want to convert the PDF to and Image, then get the byte array of the image, and save that to the database. I really don't want to save the image to a specified path.
PDFDocumentProcessor is a DevExpress class that pulls in the PDF and also will give me the PDF's byte array, but I just can't seem to find a way past the save error to retrieve an Image byte array
Any help is appreciated thank you
The issue is likely caused by you trying to re-use the same MemoryStream that is holding the input file bytes. You should create a new memory stream to save to.
I don't have access to devexpress but I grabbed another Nuget package that i am associated with https://www.nuget.org/packages/Leadtools.Pdf/ and tested it and this code works to save the PDF to a PNG memorystream:
using (var ms = new MemoryStream(fileBytes))
using (var codecs = new RasterCodecs())
{
codecs.Options.Load.AllPages = true;
using (var rasterImage = codecs.Load(ms))
using (var outputStream = new MemoryStream())
codecs.Save(rasterImage, outputStream, RasterImageFormat.Png, 0);
}

Transforming a PNG image in application/x-recordio-protobuf for calling a sagemaker endpoint in C#

I am trying to do some inferences on a SageMaker endpoint in C# using a InvokeEndpointRequest object. My inference body is a PNG or JPEG image. However, SageMaker requires an application/x-recordio-protobuf format. How can I convert my image file into this format to be able to use InvokeEndpoint with the above object.
InvokeEndpointRequest invokeRequest = new InvokeEndpointRequest
{
EndpointName = "kmeans-2019-xx-xx-xx-xx-xx-xxx",
Body= GetImageFromFile(),
ContentType= "application/x-recordio-protobuf"
};
InvokeEndpointResponse invokeResponse = smClient.InvokeEndpoint(invokeRequest);
For the moment the GetImageFromFile method just reads an image file and transforms it in MemoryStream:
Stream stream = openFileDialog.OpenFile();
byte[] data = new byte[stream.Length];
stream.Read(data, 0, (int)stream.Length);
MemoryStream ms=new MemoryStream(data);
return ms;
I tried to serialize the MemoryStream by using Protobuf-net, but it does not work.
You can first convert your PNG image into a numpy array (this can be done using PIL, OpenCV, or through other libraries).
Once you have the image represented as a ndarray, convert it to protobuf recordIO format as shown in this example.

How to insert List<> values into SQL Binary field using C#

I'm not entirely new to programming but I still see myself as a novice. I'm currently creating an Invoicing system with a max of 5 line items, this being said, I'm creating a String<> item, serializing it to store and then de-serializing it to display.
So far I've managed the serializing, and de-serializing, and from the de-serialized value I've managed to display the relevant information in the correct fields.
My question comes to: HOW do I add the list of items in the String<> object to either a Binary or XML field in my SQL table?
I know it should be similar to adding an Image object to binary but there's a catch there. usually:
byte[] convertToByte(string sourcePath)
{
//get the byte file size of image
FileInfo fInfo = new FileInfo(sourcePath);
long byteSize = fInfo.Length;
//read the file using file stream
FileStream fStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read);
//read again as byte using binary reader
BinaryReader binRead = new BinaryReader(fStream);
//convert image to byte (already)
byte[] data = binRead.ReadBytes((int)byteSize);
return data;
}
this kind of thing is done for an image however the whole "long" thing does not apply to the List<> object.
Any assistance would be helpful
If you simply want to store your data as "readable" text, you can use the varchar(MAX) or nvarchar(MAX) (depending on whether you need extended character support). That translates directly into a string in ADO.NET or EntityFramework.
If all you need are bytes from a string, the Encoding class will do that:
System.Text.Encoding.Default.GetBytes(yourstring);
See: http://msdn.microsoft.com/en-us/library/ds4kkd55%28v=vs.110%29.aspx
A way of saving a binary file in a string is to convert the image to a Base64 string. This can be done with the Convert.ToBase64String (Byte[]) method:
Convert.ToBase64String msdn
string convertImageToBase64(string sourcePath)
{
//get the byte file size of image
FileInfo fInfo = new FileInfo(sourcePath);
long byteSize = fInfo.Length;
//read the file using file stream
FileStream fStream = new FileStream(sourcePath, FileMode.Open, FileAccess.Read);
//read again as byte using binary reader
BinaryReader binRead = new BinaryReader(fStream);
//convert image to byte (already)
byte[] data = binRead.ReadBytes((int)byteSize);
return Convert.ToBase64String (data);
}
Now you will be able to save the Base64 string in a string field in your database.

Base64Encoded bitmap - convert to bitmap manually

I know I can use
string base64Encoded = ...;
byte[] byteArray = Convert.FromBase64String(this.base64Encoded); // array size [31591]
var memoryStream = new MemoryStream(byteArray);
var bitmap = new Bitmap(memoryStream);
//byte[,] im = new byte[a.Width*a.Height,3];
// array size [891998, 3] - why this array is 90 times bigger?
but I want to do it manually.
What I really need is to know how from byteArray I can create 3dim pixel array [bitmap.width * bitmap.hight, 3 {Red,Green,Blue}]
1- size of byteArray is different from size of bitmap since bitmap is actually an uncompressed 24 bit image without a header, but byteArray is a compressed (RLE most likely) bitmap file.
2- you can use libbmp or another image processing library to load and manipulate pixels. These libraries are much better at handling that kind of stuff.
3- most bitmaps are compressed using RLE compression and bitmap is a very simple format. You can actually write a bitmap reader to read it to a byte array intead of Bitmap object.

Changing Bitmaps using c#

I was working on my college project where i was trying to change bit values of a Bitmap.
I am loading the bitmap to the memory stream, then extracting it to byte[] array. Now I was changing few central bits of this byte[] array and then converting it back to a bitmap image.
But i got a run time exception that "Invalid Bitmap".
Does a bitmap have some special format instead of simple bits???
Following is the code used by me:
MemoryStream mstream = new MemoryStream();
Bitmap b = new Bitmap(#"D:\my_pic.bmp");
b.Save(mstream, System.Drawing.Imaging.ImageFormat.Bmp);
byte[] ba = mstream.ToArray();
mstream.Close();
byte[] _Buffer = null;
System.IO.FileStream _FileStream = new System.IO.FileStream(_FileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);
System.IO.BinaryReader _BinaryReader = new System.IO.BinaryReader(_FileStream);
long _TotalBytes = new System.IO.FileInfo(_FileName).Length;
_Buffer = _BinaryReader.ReadBytes((Int32)_TotalBytes);
// close file reader
_FileStream.Close();
_FileStream.Dispose();
_BinaryReader.Close();
int leng1 = ba.Length;
int leng2=_Buffer.Length;
for(i=(leng1)/2;i<leng1;i++)
{
for(j=0;j<leng2;j++)
{
ba[i]=_Buffer[j];
}
if(j==(leng2-1))
{
break;
}
}
TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
Bitmap bitmap1 = (Bitmap)tc.ConvertFrom(ba);
You must have your own goal to want to operate at this low level with a bitmap and that's fine. Unless you are performance bound it is way easier to do graphics at the graphics API level. Even if you are performance sensitive, other people have cut a path through the jungle already.
Back to the question. The BMP file format is simpler than some others but still comes in many varieties. Here is a detailed introduction to the gory details of the BMP format:
BMP file format
Now if you are just parsing your own BMP files and you know they are 32-bit RGB, and the header is going to be such-and-such a size which you can skip over, etc, then that might work for you. If you need to handle any old BMP it gets messy real fast which is why the libraries try to take care of everything for you.

Categories

Resources