I'm using PDFSharp and I'm creating pdf's from a bitmap image. I can save and view the image as a pdf no problem. But now what I want to do is before the pdf is saved as an actual file, I want to convert it to byte[]. I can save it as a byte[] after the fact I save it. I'm going to have two different methods, one that saves the pdf to a file where the user can then open it, and another that saves the pdf to byte that will be sent to a databse, but I may not do both. I may need to save a file one day and another save it as a byte without needing to save it as a file. WhatI have:
public void DrawImage(Bitmap thumbnail)//thumbnail is created with another method
{
PdfDocument document = new PdfDocument();
document.Info.Title = "Created with PDFsharp";
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
XImage image = XImage.FromGdiPlusImage(thumbnail);
gfx.DrawImage(image, 0, 0, 612, 792);
string filename = string.Format(#"{0}.pdf", Guid.NewGuid());
//This is Save(string path), there is also a Save(memoryStream stream)
document.Save(filename);
//so before I save it as a *.PDF I would like to save it as byte[] that can be sent to a Database, and eventually read from and convert the byte to a viewable *.pdf
//This saves a Bitmap as a pdf successfully
}
I hope I'm making sense, I can explain further if needed
You can use MemoryStream for this purpose:
byte[] pdfData;
using (var ms = new MemoryStream()) {
document.Save(ms);
pdfData = ms.ToArray();
}
Try using a MemoryStream:
using(var ms = new MemoryStream()){
document.Save(ms);
byte[] bytes = ms.ToArray();
}
Related
I have an image in the png format which I would like to load and convert to a bmp stream. The code I'm using to achieve this is the following:
// Image.FromFile yields the same result.
FileStream originalFile = File.Open("image.png", FileMode.Open);
System.Drawing.Image fileImage = System.Drawing.Image.FromStream(originalFile);
MemoryStream bmpStream = new MemoryStream();
fileImage.Save(bmpStream, System.Drawing.Imaging.ImageFormat.Bmp);
Result: https://pastebin.com/raw/p1TBjnD1
However the stream this produces is different from when saving to a file and opening it like this:
FileStream originalFile = File.Open("image.png", FileMode.Open);
System.Drawing.Image fileImage = System.Drawing.Image.FromStream(originalFile);
FileStream bmpStream;
fileImage.Save("image.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
bmpStream = File.Open("image.bmp", FileMode.Open);
Result: https://pastebin.com/raw/vSdRwZpL
There appears to be some kind of header missing when saving to a stream. Why is this, and how can I easily add it to my streams without having to save to files?
My question is not how to do this, but why the stream doesn't include this header while the file does.
They are not different but when you dump or copy or do something else with memory stream you always have to reset it to its initial position.
fileImage.Save(bmpStream, System.Drawing.Imaging.ImageFormat.Bmp);
bmpStream.Position = 0
... now you can dump or save to file from bmpStream
If you do not reset the position, you might read nothing back from the MemoryStream. In the case of Image.Save(), it is even more tricky because the Save method puts the MemoryStream position at the beginning of the image data (after the header) assuming this is what you want.
I Have gif image in base64.
Currently I am approaching this way. reading base64 gif file and writing it to byte array and writing it back to image file to disk and reading from the file to picturebox.image.
byte[] imageBytes = Convert.FromBase64String(body);
//* this is write file to disk and read
string filename = Username;
File.WriteAllBytes(filename, imageBytes);
fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
pictureBox1.Image = Image.FromStream(fs);
Now, I want to write it to memory without writing it to disk file. like in a form of variable image. that can be assigned to picturebox. Is there any possible of this. because I have to do repeatedly many times for many images.
So I would like find a different approach without writing saving file to disk and reading it again.
Any help appreciated.
byte[] imageBytes = Convert.FromBase64String(body);
MemoryStream stream = new MemoryStream(imageBytes);
pictureBox1.Image = Image.FromStream(stream);
byte[] imageBytes = Convert.FromBase64String(body);
using (var ms = new MemoryStream(imageBytes))
{
pictureBox1.Image = Image.FromStream(ms);
}
Be aware the MemoryStream class is IDisposable so you should Dispose() it. This can happen with using or with try/catch/finally block.
I have an image on a page, e.g <img id="img3" runat="server" src="image.jpg" width="200" height="200"/> and I'd like to save the image referenced by the src attribute in my database using stored procedure.
I should convert the image to binary first.
Here is what I have so far:
Stream fs = FileUpload1.PostedFile.InputStream;
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
cmd.Parameters.AddWithValue("#img", byte);
But the thing is that I don't want to save the uploaded image FileUpload1.PostedFile.InputStream, I want to save the image that I had its src.
Is there a way to put the image src in stream so that I can save it or what is the right way for doing that?
Generally it is not recommended to store images in Database or any other type of files in RDBMS. What is most effective way, to store the file over disk on server, and store that path in your table.
So whenever you need to reference that image/file, then fetch the path from the database, and read the file from disk. This broadly has following two benefits.
Removes the extensive conversion process (from image to binary and
vice-versa).
Helps to read the image directly (soft-read).
Saving an image in the database is not recommanded, but if you insist on saving it in your database you can convert the image to base64, then save the base64 string in your database.
using (Image image = Image.FromStream(FileUpload1.PostedFile.InputStream))
{
using (MemoryStream m = new MemoryStream())
{
image.Save(m, image.RawFormat);
byte[] imageBytes = m.ToArray();
// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
//Now save the base64String in your database
}
}
And to convert it back from base64 to an image:
public Image GetImageFromBase64String(string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
I combined some code from converting a base 64 string to an image and saving it
and from Convert image path to base64 string .
How to convert Byte array to an image and open with some process (such as Windows Photo Viewer)?
In here i don't want to convert array data to an image file and save it in the disk, what i would like to do is to convert byte array to a memory stream or such a thing and using this i want to open that specific image.
Is it possible? (not to show them in a picture box or such a thing).
You will not be able to open it in an external viewer unless it's a file. However, if you don't care about that file, use a temporary one:
public void ViewImage(Byte[] ImageBytes)
{
try
{
Byte[] ba = new Byte[1];
using (MemoryStream ms = new MemoryStream(ba))
{
Image img = Image.FromStream(ms);
String tmpFile = Path.GetTempFileName();
tmpFile = Path.ChangeExtension(tmpFile, "jpg");
img.Save(tmpFile);
if (File.Exists(tmpFile))
Process.Start(tmpFile); //Windows will use file association to open a viewer
}
}
catch (OutOfMemoryException ex)
{
//React appropriately
}
}
Since this forces saving the image as a JPG, if the type of the original image is important, more logic should be added to deal with that fact.
I am trying to create a pdf file with iTextSharp. My attempt writes the content of the pdf to a MemoryStream so I can write the result both into file and a database BLOB. The file gets created, has a size of about 21kB and it looks like a pdf when opend with Notepad++. But my PDF viewer says it's currupted.
Here is a little code snippet (only tries to write to a file, not to a database):
Document myDocument = new Document();
MemoryStream myMemoryStream = new MemoryStream();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Content of the pdf gets inserted here
using (FileStream fs = File.Create("D:\\...\\aTestFile.pdf"))
{
myMemoryStream.WriteTo(fs);
}
myMemoryStream.Close();
Where is the mistake I make?
Thank you,
Norbert
I think your problem was that you weren't properly adding content to your PDF. This is done through the Document.Add() method and you finish up by calling Document.Close().
When you call Document.Close() however, your MemoryStream also closes so you won't be able to write it to your FileStream as you have. You can get around this by storing the content of your MemoryStream to a byte array.
The following code snippet works for me:
using (MemoryStream myMemoryStream = new MemoryStream()) {
Document myDocument = new Document();
PdfWriter myPDFWriter = PdfWriter.GetInstance(myDocument, myMemoryStream);
myDocument.Open();
// Add to content to your PDF here...
myDocument.Add(new Paragraph("I hope this works for you."));
// We're done adding stuff to our PDF.
myDocument.Close();
byte[] content = myMemoryStream.ToArray();
// Write out PDF from memory stream.
using (FileStream fs = File.Create("aTestFile.pdf")) {
fs.Write(content, 0, (int)content.Length);
}
}
I had similar issue. My file gets downloaded but the file size will be 13Bytes. I resolved the issue when I used binary writer to write my file
byte[] bytes = new byte[0];
//pass in your API response into the bytes initialized
using (StreamWriter streamWriter = new StreamWriter(FilePath, true))
{
BinaryWriter binaryWriter = new BinaryWriter(streamWriter.BaseStream);
binaryWriter.Write(bytes);
}
Just some thoughts - what happens if you replace the memory stream with a file stream? Does this give you the result you need? This will at least tell you where the problem could be.
If this does work, how do the files differ (in size and binary representation)?
Just a guess, but have you tried seeking to the beginning of the memory stream before writing?
myMemoryStream.Seek(0, SeekOrigin.Begin);
Try double checking your code that manipulates the PDF with iText. Make sure you're calling the appropriate EndText method of any PdfContentByte objects, and make sure you call myDocument.Close() before writing the file to disk. Those are things I've had problems with in the past when generating PDFs with iTextSharp.
documentobject.Close();
using (FileStream fs = System.IO.File.Create(path)){
Memorystreamobject.WriteTo(fs);
}