How to use Magick.net to convert HttpPostedFile .heic to .jpg - c#

I have a .NET c# web application that allows users to upload images. I installed the Magick.NET NuGet package. I'm attempting to convert uploaded .heic files to .jpg but I'm not sure where to start.
Here's the upload without Magick.net.
string fullPath = path + #"\Images\" + fileName;
Image image = Image.FromStream(postedFile.InputStream);
image.Save(path);
Here's what I'm trying but I get the following error: Parameter is not valid
string fullPath = path + #"\Images\" + fileName;
Bitmap bitmap = new Bitmap(postedFile.InputStream); <-- ERROR
using (MagickImage i = new MagickImage(bitmap))
{
i.Format = MagickFormat.Jpg;
using (MemoryStream memStream = new MemoryStream(i.ToByteArray()))
{
image = Image.FromStream(memStream);
}
}
image.Save(path);
Here's another approach that's similar to the Magick.net documentation but I get the following error: Attempt by security transparent method to access security critical method failed. Assembly marked with the AllowPartiallyTrustedCallersAttribute and uses the level 2 security transparency model. Level 2 transparency causes all methods in AllowPartiallyTrustedCallers assemblies to become security transparent by default, which may be the cause of this exception.
string fullPath = path + #"\Images\" + fileName;
Stream fs = postedFile.InputStream;
BinaryReader br = new System.IO.BinaryReader(fs);
byte[] bytes = br.ReadBytes((Int32)fs.Length);
using (MemoryStream memStream = new MemoryStream())
{
using (MagickImage i = new MagickImage(bytes)) <-- ERROR
{
i.Format = MagickFormat.Jpg;
image = Image.FromStream(memStream);
}
}
image.Save(path);
Anyone have any suggestions?

You don't need to instantiate a bitmap for that, and that error is probably because of your stream position (you need to set it to 0).
Here's what I did to make this work
postedFile.InputStream.Position = 0; //just to avoid the Parameter is not valid error in case you did any previous manipulation with this
using (MagickImage i = new MagickImage(postedFile.InputStream))
{
i.Format = MagickFormat.Jpg;
using (MemoryStream memStream = new MemoryStream(i.ToByteArray()))
{
image = Image.FromStream(memStream);
}
}

Related

How to solve 'Could not find a part of the path..' issue on server

I'm using Zxing library to create a barcode and memory stream to save it to the server folder.
Everything works fine on local as well as a testing server, but when I publish code on client-server it won't create a barcode image nor get location of image on that server location.
Here is the code I created for this process-
var writer = new BarcodeWriter();
writer.Format = BarcodeFormat.CODE_128;// QR_CODE;
var result = writer.Write(printArray[0]);
string path = Server.MapPath("/images/code/" + ComplaintId + ".jpg");
var barcodeBitmap = new Bitmap(result);
using (MemoryStream memory = new MemoryStream())
{
using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite))
{
barcodeBitmap.Save(memory, ImageFormat.Jpeg);
byte[] bytes = memory.ToArray();
fs.Write(bytes, 0, bytes.Length);
}
}
This code is used to save bar code on the server location.
string ImagePath = ComplaintId + ".jpg";
imgQRcode.Src = "~/images/code/" + ImagePath;
and used this line to bind it to img tag.
it shows error like
Could not find a part of the path g:\xyz\images\code\103.jpg
this only happen on client-server not elsewhere.
---------Edit 1--------
As I was still facing issues while creating image on a host server, I made a few changes in code now. Instead of saving barcode image I'm converting it to Base64 string and using it.
Here is code changes
var barWriter = new BarcodeWriter();
barWriter.Format = BarcodeFormat.CODE_128;// QR_CODE;
var barResult = barWriter.Write("printbar");
var barcodeBitmap = new Bitmap(barResult);
string bs64 = ToBase64String(barcodeBitmap, ImageFormat.Jpeg);
and Tobase64String function
public static string ToBase64String(Bitmap bmp, ImageFormat imageFormat)
{
string base64String = string.Empty;
MemoryStream memoryStream = new MemoryStream();
bmp.Save(memoryStream, imageFormat);
memoryStream.Position = 0;
byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
base64String = Convert.ToBase64String(byteBuffer);
byteBuffer = null;
return base64String;
}
and function to bind base64 to image
public static string GetImageSrc(string base64Src)
{
return "data:image/png;base64," + base64Src;
}
to feed it to iTextcharp use
byte[] imageBytes = Convert.FromBase64String(bs64);
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imageBytes);

Can't use Image.FromStream for .ai file

I am trying to convert an .ai file to Image, but the line
Image.FromStream(new MemoryStream(Utils.LoadImage("icon.ai")))
returns invalid operation exception.
The function Utils.LoadImage returns a byte[].
Here is the rest of the code:
ZipArchiveEntry hus_icon = zip.CreateEntry("icon.ai");
using (Stream photoStream = hus_icon.Open())
{
var image = Image.FromStream(new MemoryStream(Utils.LoadImage("icon.ai")));
var imageBmp = new Bitmap(image);
imageBmp.Save(photoStream, image.RawFormat);
}

Convert Base64 from PDF to Bitmap [duplicate]

Is there any way, I can convert HTML Document (file not URL) to Image, or PDF to image?
I am able to do the above using Ghostscript DLL , Is there any other way , I can do it, without using the Ghostscript DLL?
I am developing a C# Windows Application.
the best and free nuget package that you can save every page of your Pdf to png and with custom resilution Docnet.core this can be use in the .net core project.
they have github and nice examples but here i want to add my code for reading en pdf with more that one page
string webRootPath = _hostingEnvironment.WebRootPath;
string fullPath = webRootPath + "/uploads/user-manual/file.pdf";
string fullPaths = webRootPath + "/uploads/user-manual";
using (var library = DocLib.Instance)
{
using (var docReader = library.GetDocReader(fullPath, 1080, 1920))
{
for (int i = 1; i < docReader.GetPageCount(); i++)
{
using (var pageReader = docReader.GetPageReader(i))
{
var bytes = EmailTemplates.GetModifiedImage(pageReader);
System.IO.File.WriteAllBytes(fullPaths+"/page_image_" +i+".png", bytes);
}
}
}
}
Other functions you can find in thier github repo.
Use LibPdf, for PDF to Image conversion
LibPdf library converts converts PDF file to an image. Supported image formats are PNG and BMP, but you can easily add more.
Usage example:
using (FileStream file = File.OpenRead(#"..\path\to\pdf\file.pdf")) // in file
{
var bytes = new byte[file.Length];
file.Read(bytes, 0, bytes.Length);
using (var pdf = new LibPdf(bytes))
{
byte[] pngBytes = pdf.GetImage(0,ImageType.PNG); // image type
using (var outFile = File.Create(#"..\path\to\pdf\file.png")) // out file
{
outFile.Write(pngBytes, 0, pngBytes.Length);
}
}
}
ImageMagick, you should also look at this freely available and powerful tool. It's capable of doing what you want and also provides some .NET bindings (as well as bindings to several other languages).
In its simplest form, it's just like writing a command
convert file.pdf imagefile.png
Try Freeware.Pdf2Png, check below url:
PDF to PNG converter.
byte[] png = Freeware.Pdf2Png.Convert(pdf, 1);
https://www.nuget.org/packages/Freeware.Pdf2Png/1.0.1?_src=template
In the about info, It said MIT license, I check it on March 22, 2022.
But as said Mitya, please double check.
You can use below any one library for PDF to Image conversion
Use Aspose.pdf link below:
http://www.aspose.com/docs/display/pdfnet/Convert+all+PDF+pages+to+JPEG+Images
code sample:
Aspose.Pdf.Document pdfDocument = new Aspose.Pdf.Document(MyPdfPath));
using (FileStream imageStream = new FileStream(MyOutputImage.png, FileMode.Create))
{
Resolution resolution = new Resolution(300);
PngDevice pngDevice = new PngDevice(resolution);
pngDevice.Process(pdfDocument.Pages[PageNo], MyOutputImage);
imageStream.Close();
}
Use Bytescout PDF Renderer link below:
http://bytescout.com/products/developer/pdfrenderersdk/convert-pdf-to-png-basic-examples
code sample :
MemoryStream ImageStream = new MemoryStream();
RasterRenderer renderer = new RasterRenderer();
renderer.RegistrationName = "demo";
renderer.RegistrationKey = "demo";
// Load PDF document.
renderer.LoadDocumentFromFile(FilePath);
for (int i = 0; i < renderer.GetPageCount(); i++)
{
// Render first page of the document to PNG image file.
renderer.RenderPageToStream(i, RasterOutputFormat.PNG, ImageStream);
}
Image im = Image.FromStream(ImageStream);
im.Save("MyOutputImage.png");
ImageStream.Close();
Using docnet, based in this example on github, I did this, very simple and functional :
pdf used in this example.
//...
using Docnet.Core;
using System.IO;
using Docnet.Core.Models;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
//paths
string pathPdf = #"C:\pathToPdfFile\lorem-ipsum.pdf";
string finalPathWithFileName = #"C:\pathToFinalImageFile\finalFile.png";
//using docnet
using (var docReader = DocLib.Instance.GetDocReader(pathPdf, new PageDimensions(1080, 1920)))
{
//open pdf file
using (var pageReader = docReader.GetPageReader(0))
{
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
var characters = pageReader.GetCharacters();
//using bitmap to create a png image
using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
{
AddBytes(bmp, rawBytes);
using (var stream = new MemoryStream())
{
//saving and exporting
bmp.Save(stream, ImageFormat.Png);
File.WriteAllBytes(finalPathWithFileName, stream.ToArray());
};
};
};
};
//extra methods
private static void AddBytes(Bitmap bmp, byte[] rawBytes)
{
var rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
var bmpData = bmp.LockBits(rect, ImageLockMode.WriteOnly, bmp.PixelFormat);
var pNative = bmpData.Scan0;
Marshal.Copy(rawBytes, 0, pNative, rawBytes.Length);
bmp.UnlockBits(bmpData);
}
Spire.PDF library can be used for PDF to Image conversion, such as PDF to PNG, JPG, EMF and TIFF etc.
The following is the code example shows how to convert PDF to PNG:
//Load a PDF
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("PdfFilePath");
//Save to PNG images
for (int i = 0; i < doc.Pages.Count; i++)
{
String fileName = String.Format("ToImage-img-{0}.png", i);
using (Image image = doc.SaveAsImage(i,300,300))
{
image.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
}
}
doc.Close();
More conversion examples can be found in the library's documentation. It also provides a free community edition but with some limitations.
While using Ghostscript with ImageMagick is a potential option, it is incredibly slow, every page would take around 5 or more seconds. DocNet is a much better option to convert pdf to images. The following code would convert all pages in a pdf file into Images, and do that fast.
public void SavePDFtoJPGDocnet(string fileName)
{
string FilePath = #"C:\SampleFileFolder\doc.pdf";
string DestinationFolder = #"C:\SampleFileFolder\";
IDocLib DocNet = DocLib.Instance;
//you are specifying the max resolution of image on any side, actual resolution will be limited by longer side,
//preserving the aspect ratio
var docReader = DocNet.GetDocReader(
FilePath,
new PageDimensions(1440, 2560));
for (int i = 0; i < docReader.GetPageCount(); i++)
{
using (var pageReader = docReader.GetPageReader(i))
{
var rawBytes = pageReader.GetImage();
var width = pageReader.GetPageWidth();
var height = pageReader.GetPageHeight();
var characters = pageReader.GetCharacters();
var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb);
DocnetClass.AddBytes(bmp, rawBytes);
//DocnetClass.DrawRectangles(bmp, characters);
var stream = new MemoryStream();
bmp.Save(stream, ImageFormat.Png);
File.WriteAllBytes(DestinationFolder + "/page_image_" + i + ".png", stream.ToArray());
}
}
}
Freeware.Pdf2Png worked great for my needs.
It does not only convert to Png, you can save to the image format of your choice.
In MS Visual Studio run this in your Package Manager console
PM> NuGet\Install-Package Freeware.Pdf2Png -Version 1.0.1,
or just add via the NuGet Package Manager GUI, search for Freeware.Pdf2Png and it should come up.
Once the reference is added to your project, code similar to this should do what you need to convert a PDF to an Image.
using (FileStream fs = new FileStream(FullFilePath, FileMode.Open))
{
byte[] buff = Freeware.Pdf2Png.Convert(fs, 1);
MemoryStream ms = new MemoryStream(buff);
Image img = Image.FromStream(ms);
img.Save(TiffFilePath, System.Drawing.Imaging.ImageFormat.Tiff);
}
FullFilePath - a string that is the Full File Path to the PDF to be converted.
TiffFilePath - a string that is the Full File Path of the newly created Image that you would like to save.
Unfortunately I was not able to find any c# code or proper algorithm to do this conversion without a 3rd party DLL. If any of you have good information for that please do share it!
In case someone wants to use Ghostscript.NET.
Ghostscript.NET - (written in C#) is the most completed managed wrapper library around the Ghostscript library (32-bit & 64-bit), an interpreter for the PostScript language, PDF.
It is dependent on executable file you have to install on your machine. Here is a link from where you can see and download the latest version of the exe.
https://www.ghostscript.com/download/gsdnld.html
P.S. I had some troubles with the latest version 9.50 not being able to count the pages.
I prefer using the 9.26 version.
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw32.exe
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw64.exe
Next step is to find and install Ghostscript.NET from Nuget.
I download the PDF from CDN url and use the MemoryStream to open and process the PDF file. Here is a sample code:
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
using (var ms = new MemoryStream(buffer))
{
rasterizer.Open(ms);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
You can also use it with temporary FileStream. Here is another example. Note that the File is temporary and has DeleteOnClose mark.
using (WebClient myWebClient = new WebClient())
{
using (GhostscriptRasterizer rasterizer = new GhostscriptRasterizer())
{
/* custom switches can be added before the file is opened
rasterizer.CustomSwitches.Add("-dPrinted");
*/
byte[] buffer = myWebClient.DownloadData(pdfUrl);
int bufferSize = 4096;
using (var fileStream = System.IO.File.Create("TempPDFolder/" + pdfName, bufferSize, System.IO.FileOptions.DeleteOnClose))
{
// now use that fileStream to save the pdf stream
fileStream.Write(buffer, 0, buffer.Length);
rasterizer.Open(fileStream);
var image = rasterizer.GetPage(0, 0, 1);
var imageURL = "MyCDNpath/Images/" + filename + ".png";
_ = UploadFileToS3(image, imageURL);
}
}
}
Hope it will help someone struggling to get high quality images from pdf for free.

How to read image dimensions at C# wpf - there is no dispose method for BitmapImage

With the way below i am able to read.
But there is no dispose method so i am not able to delete the file later.
So the below method is getting failed.
I could not come up with a proper solution.
Bitmap class is not recognized in C# 4.5 WPF application.
thank you
DirectoryInfo dInfo = new DirectoryInfo(#"C:\pokemon_files\images\");
FileInfo[] subFiles = dInfo.GetFiles();
BitmapImage myImg;
foreach (var vrImage in subFiles)
{
string srFilePath = vrImage.FullName;
System.Uri myUri = new Uri(srFilePath);
myImg = new BitmapImage(myUri);
if (myImg.Width < 50)
{
File.Delete(srFilePath);
continue;
}
}
I assume the error you get is caused by trying to delete the file which is currently in use
by the bitmap (I don't remember the exception name).
There is a solution to that, that is: making a byte stream.
byte[] imageData;
using(var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
using(var binaryReader = new BinaryReader(fileStream))
{
imageData = binaryReader.ReadBytes((int)fileStream.Length);
}
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = new MemoryStream(imageData);
bitmap.EndInit();
//Now you can check the width & height, the file stream should be closed so you can
//delete the file.
[EDIT]
If you don't want to read the bytes by BinaryReader, there's always this solution if you want to read all bytes from the file.

ArgumentException when converting byte[] to Bitmap c#

I'm trying to convert a byte array to a bitmap but it always shows me:
System.ArgumentException: Parameter is not valid.
My code is as follows:
I'm passing the bytes through a webservice with:
string DecodedString = string.Empty;
DecodedString = System.Text.Encoding.GetEncoding(1251).GetString(bytes);
sResult = sResult + "<Photo>" +XmlConvert.EncodeName(DecodedString) + "</Photo>";
and in my webPage:
byte[] bytes = (Byte[])System.Text.Encoding.GetEncoding(1251).GetBytes(XmlConvert.DecodeName(xDocument.SelectSingleNode("Response/Images/Photo").InnerText));
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = new System.Drawing.Bitmap(ms);//(System.Drawing.Image.FromStream(ms));
Try passing the string as a Base64:
string DecodedString = string.Empty;
DecodedString = System.Convert.ToBase64String(bytes)
sResult = sResult + "<Photo>" +XmlConvert.EncodeName(DecodedString) + "</Photo>";
...
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = System.Drawing.Image.FromStream(ms);
You also won't need to use XmlConvert to encode/decode the string.
I did it, with the help of all of you, here is my page code
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
System.Drawing.Bitmap b = new System.Drawing.Bitmap(ms); //(Bitmap)System.Drawing.Image.FromStream(ms);
System.Drawing.Imaging.FrameDimension frameDim;
frameDim = new System.Drawing.Imaging.FrameDimension(b.FrameDimensionsList[0]);
int NumberOfFrames = b.GetFrameCount(frameDim);
string[] paths = new string[NumberOfFrames];
for (int i = 0; i < NumberOfFrames; i++)
{
b.SelectActiveFrame(frameDim, i);
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(b);
paths[i] = imagePathfile.Remove(imagePathfile.Length - 4, 4) + i.ToString() + ".gif";
bmp.Save(paths[i], System.Drawing.Imaging.ImageFormat.Gif);
//bmp.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);
bmp.Dispose();
}
Image1.Src = paths[0];
//Check if there's more than 1 image cause its a TIFF
if (paths.Length>1)
{
Image2.Src = paths[1];
}
I had a similar problem recently, but using Silverlight. I ended up needing to create a Custom HTTP Handler in order to pass the byte[] that defined the image back as a stream.
See http://www.dotnetcurry.com/ShowArticle.aspx?ID=220
Edit: This allows you to avoid worrying about XML encoding, and passes the image back in Binary form... YMMV
According to MSDN:
ArgumentException - The stream does not have a valid image format
I believe your problem is in the original byte[] array you are passing to the web service.
According to one of your comments, you did:
System.IO.FileStream fs = new System.IO.FileStream(sPath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
int streamLength = Convert.ToInt32(fs.Length);
bytes = new byte[streamLength];
fs.Read(bytes, 0, streamLength);
fs.Read returns the number of bytes that have been read into the byte array; it doesn't always read the entire file!
Try using the StreamFile method from http://www.dotnetspider.com/resources/4515-convert-file-into-byte-array.aspx. (First result of Google search)
Try this:
byte[] bytes = System.Convert.FromBase64String(xDocument.SelectSingleNode("Response/Images/Photo").InnerText);
System.Drawing.ImageConverter imageConverter = new System.Drawing.ImageConverter();
Image image = imageConverter.ConvertFrom(bytes) as Image;
System.Drawing.Bitmap b = new System.Drawing.BitMap(image);
EDIT
Take a look at this:
Transfer any files on Web services by c#
actually i had been meet this problem, In my case, when i use IE browser, it is ok but when use another browser it always have the same error.
"Parameter is not valid exception is always happening in the same line of code:
System.Drawing.Image.FromStream(ms));"
So i think it seems this issue depend on browser and type of image (JPEG,JPEG2000).
Here is some code I used converting bytes to an image for a unit test:
protected override Image LoadImage()
{
//get a temp image from bytes, instead of loading from disk
//data:image/gif;base64,
byte[] bytes = Convert.FromBase64String("R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==");
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
To my understanding, the image can not be shown because the format of the image's bytes is not correct. Every image format has its own head or something.

Categories

Resources