File being used (without opening it) c# - c#

I got a strange error with this program, It download a photo from internet, then I convert it to .jpeg and then I delete the first photo (in .png).
But i got an error: File is being used by another process. Why is happening this? I didn't open the file, and nobody is using it.
string outFile;
outFile = Path.GetTempFileName();
try
{
webClient.DownloadFile(foto, outFile);
if (foto.Substring(foto.Length - 3) == "png")
{
System.Drawing.Image image1 = System.Drawing.Image.FromFile(outFile);
foto = foto.Remove(foto.Length - 3) + "jpg";
string outFile2 = Path.GetTempFileName();
image1.Save(outFile2, System.Drawing.Imaging.ImageFormat.Jpeg);
System.IO.File.Delete(outFile);
outFile = outFile2;
}
}

FromFile is keeping the file open, you have to use something like this:
// Load image
FileStream filestream;
filestream = new FileStream("Filename",FileMode.Open, FileAccess.Read);
currentImage = System.Drawing.Image.FromStream(filestream);
filestream.Close();

The system.Drawing.Image is holding on to the file, Just wrap the image1 in a using statement.
string foto = "http://icons.iconarchive.com/icons/mazenl77/I-like-buttons/64/Style-Config-icon.png";
string outFile = Path.GetTempFileName();
WebClient webClient = new WebClient();
try
{
webClient.DownloadFile(foto, outFile);
if (Path.GetExtension(foto).ToUpper() == ".PNG")
{
string outFile2 = Path.GetTempFileName();
using (System.Drawing.Image image1 = System.Drawing.Image.FromFile(outFile))
{
image1.Save(outFile2, System.Drawing.Imaging.ImageFormat.Jpeg);
}
System.IO.File.Delete(outFile);
}
}

Related

System.IO.Compression "Image can´t open because format not compatible or damage"

I'm creating and downloading a .zip folder with images inside, but the images are damaged or corrupted and I don´t know how to fix it.
try{
byte[] retVal = null;
query = "Select query";
OrderList = BringDeliveryImageDirectories(query);
using (var memoryStream = new MemoryStream())
{
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (var list in orderList)
{
ImageName = list.getImgFrontDni_tr().Split("/");
var file1 = archive.CreateEntry(imageName[5]);
using(BinaryWriter streamWriter = new BinaryWriter(file1.Open()))
{
streamWriter.Write(System.IO.File.ReadAllBytes("wwwroot" + list.getImgFrenteDni_tr()),0,("wwwroot" + list.getImgFrenteDni_tr()).Length);
streamWriter.Close();
}
ImageName = list.getImgDniDni_tr().Split("/");
var file2 = archive.CreateEntry(imageName[5]);
using(BinaryWriter streamWriter = new BinaryWriter(file2.Open()))
{
streamWriter.Write(System.IO.File.ReadAllBytes("wwwroot" + list.getImgDorsoDni_tr()),0, ("wwwroot" + list.getImgDorsoDni_tr()).Length);
streamWriter.Close();
}
}
memoryStream.Position = 0;
}
retVal = memoryStream.ToArray(); //
//return File(memoryStream, "application/zip", "Images.zip");
}
}
return File(retVal, MediaTypeNames.Application.Zip, "Images.zip");
}
I tried changing the BinaryWriter with StreamWriter, the Return File(), streamWriter.Write parameters, but nothing is fixing my problem, I searched here in Stack forum but didn't work for me.
The .zip folder is downloading and bringing all the images okey, but when I try to open an image, it says:
The image can´t open because format not compatible or damage
or also I have a popup again trying to open an image
Error to compress the folder. Windows cannot complete the extraction. Failed to create destiny file

How to convert PDF Base64 into pdf then PDF into an image in C#

following is the code added:
The image object is in the library.imaging.
"using System.Drawing;"
"using System.Drawing.Imaging;"
{
byte[] b = Convert.FromBase64String("R0lGODlhAQABAIAAA");
Image image;
using (MemoryStream memstr = new MemoryStream(b))
{
image = Image.FromStream(memstr);
}
}
Here is the new code I'm working on:
{
string base64BinaryStr = " ";
byte[] PDFDecoded = Convert.FromBase64String(base64BinaryStr);
string FileName = (#"C:\Users\Downloads\PDF " + DateTime.Now.ToString("dd-MM-yyyy-hh-mm"));
BinaryWriter writer = new BinaryWriter(File.Create(FileName + ".pdf"));
writer.Write(PDFDecoded);
string s = Encoding.UTF8.GetString(PDFDecoded);
}
So this is your current code:
byte[] PDFDecoded = Convert.FromBase64String(base64BinaryStr);
string FileName = (#"C:\Users\Downloads\PDF " + DateTime.Now.ToString("dd-MM-yyyy-hh-mm"));
BinaryWriter writer = new BinaryWriter(File.Create(FileName + ".pdf"));
writer.Write(PDFDecoded);
You don't actually need BinaryWriter for this. File.Create already gives you a FileStream:
FileStream writer = File.Create(FileName + ".pdf");
writer.Write(PDFDecoded, 0, PDFDecoded.Length);
But this will still have the problem you're experiencing because you're not flushing the data to it. We also need to close the file. Thankfully, we can wrap it in using and it will do both for us:
using (FileStream writer = File.Create(FileName + ".pdf"))
{
writer.Write(PDFDecoded, 0, PDFDecoded.Length);
}
But a simpler way to do this is:
File.WriteAllBytes(FileName + ".pdf", PDFDecoded);
As for PDF -> Image, you'll probably have to see if there is a library available for this (search "PDF to Image NuGet") that can help you with this as I don't think there is anything built-in.
Just a thought, you don't need to create a physical PDF file, you can have it in memory and convert it to image from there.
Now the problem is that you cannot use Image from System.Drawing.Imaging for this, it doesn't support reading PDF file.
Instead you'll need to search for some library that can do that.
For example, try GemBox.Pdf, you can use it like this:
string base64String = "...";
byte[] pdfBytes = Convert.FromBase64String(base64String);
using (PdfDocument pdfDocument = PdfDocument.Load(new MemoryStream(pdfBytes)))
{
ImageSaveOptions imageOptions = new ImageSaveOptions(ImageSaveFormat.Png);
string imageName = DateTime.Now.ToString("dd-MM-yyyy-hh-mm") + ".png";
pdfDocument.Save(#"C:\Users\Downloads\" + imageName, imageOptions);
}
I've used the code provided on this Convert example.

Asp .NET Read a file from a tar.gz archive

I have some files inside in one .tar.gz archive. These files are on a linux server.How can I read from a specific file inside this archive if I know it's name?
For reading direct from the txt file, I used the following code:
Uri urlFile = new Uri("ftp://" + ServerName + "/%2f" + FilePath + "/" + fileName);
WebClient req = new WebClient() { Credentials=new NetworkCredential("user","psw")};
string result = req.DownloadString(urlFile);
It's possible to read this file without copying the archive on the local machine, something like the code above?
I found a solution. Maybe this can help you guys.
// archivePath="ftp://myLinuxServer.com/%2f/move/files/archive/20170225.tar.gz";
public static string ExtractFileFromArchive(string archivePath, string fileName)
{
string stringFromFile="File not found";
WebClient wc = new WebClient() { Credentials = cred, Proxy= webProxy }; //Create webClient with all necessary settings
using (Stream source = new GZipInputStream(wc.OpenRead(archivePath))) //wc.OpenRead() create one stream with archive tar.gz from our server
{
using (TarInputStream tarStr =new TarInputStream(source)) //TarInputStream is a stream from ICSharpCode.SharpZipLib.Tar library(need install SharpZipLib in nutgets)
{
TarEntry te;
while ((te = tarStr.GetNextEntry())!=null) // Go through all files from archive
{
if (te.Name == fileName)
{
using (Stream fs = new MemoryStream()) //Create a empty stream that we will be fill with file contents.
{
tarStr.CopyEntryContents(fs);
fs.Position = 0; //Move stream position to 0, in order to read from beginning
stringFromFile = new StreamReader(fs).ReadToEnd(); //Convert stream to string
}
break;
}
}
}
}
return stringFromFile;
}

Check FileName From HttpHostedFileBase is File Name or File Path

I am developing an application which store filename in database. For Mozilla & Chrome it is showing FileName only but in IE it is showing full path of file. Now I want to check whether given filename is filename or filepath. Is there any way to do it?
Here is my code:
public ActionResult Save(IEnumerable<HttpPostedFileBase> attachments)
{
byte[] image = null;
var file = attachments.First();
// Some browsers send file names with full path. We only care about the file name.
string filePath = Server.MapPath(General.FaxFolder + "/" + file.FileName);
file.SaveAs(filePath);
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
using (BinaryReader br = new BinaryReader(fs))
{
image = br.ReadBytes((int)fs.Length);
}
TempData["Image"] = image;
System.IO.File.Delete(filePath);
return Json(new { status = "OK", imageString = Convert.ToBase64String(image) }, "text/plain");
}
Well,If you go with getting filename only in any browser then you should write
Path.GetFileName(e.fileName);
It will return filename only in any browser
Thanks
Instead of check whether the file has a path or not, what you can do is to just use
GetFileName(path);method

converting a base 64 string to an image and saving it

Here is my code:
protected void SaveMyImage_Click(object sender, EventArgs e)
{
string imageUrl = Hidden1.Value;
string saveLocation = Server.MapPath("~/PictureUploads/whatever2.png") ;
HttpWebRequest imageRequest = (HttpWebRequest)WebRequest.Create(imageUrl);
WebResponse imageResponse = imageRequest.GetResponse();
Stream responseStream = imageResponse.GetResponseStream();
using (BinaryReader br = new BinaryReader(responseStream))
{
imageBytes = br.ReadBytes(500000);
br.Close();
}
responseStream.Close();
imageResponse.Close();
FileStream fs = new FileStream(saveLocation, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
try
{
bw.Write(imageBytes);
}
finally
{
fs.Close();
bw.Close();
}
}
}
The top imageUrl declartion is taking in a Base64 image string, and I want to convert it into an image. I think my set of code only works for images like "www.mysite.com/test.jpg" not for a Base64 string. Anybody have some suggestions? Thanks!
Here is an example, you can modify the method to accept a string parameter. Then just save the image object with image.Save(...).
public Image LoadImage()
{
//data:image/gif;base64,
//this image is a single pixel (black)
byte[] bytes = Convert.FromBase64String("R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==");
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
return image;
}
It is possible to get an exception A generic error occurred in GDI+. when the bytes represent a bitmap. If this is happening save the image before disposing the memory stream (while still inside the using statement).
You can save Base64 directly into file:
string filePath = "MyImage.jpg";
File.WriteAllBytes(filePath, Convert.FromBase64String(base64imageString));
Here is what I ended up going with.
private void SaveByteArrayAsImage(string fullOutputPath, string base64String)
{
byte[] bytes = Convert.FromBase64String(base64String);
Image image;
using (MemoryStream ms = new MemoryStream(bytes))
{
image = Image.FromStream(ms);
}
image.Save(fullOutputPath, System.Drawing.Imaging.ImageFormat.Png);
}
I would suggest via Bitmap:
public void SaveImage(string base64)
{
using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64)))
{
using (Bitmap bm2 = new Bitmap(ms))
{
bm2.Save("SavingPath" + "ImageName.jpg");
}
}
}
Here is working code for converting an image from a base64 string to an Image object and storing it in a folder with unique file name:
public void SaveImage()
{
string strm = "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
//this is a simple white background image
var myfilename= string.Format(#"{0}", Guid.NewGuid());
//Generate unique filename
string filepath= "~/UserImages/" + myfilename+ ".jpeg";
var bytess = Convert.FromBase64String(strm);
using (var imageFile = new FileStream(filepath, FileMode.Create))
{
imageFile.Write(bytess, 0, bytess.Length);
imageFile.Flush();
}
}
In my case it works only with two line of code. Test the below C# code:
String dirPath = "C:\myfolder\";
String imgName = "my_mage_name.bmp";
byte[] imgByteArray = Convert.FromBase64String("your_base64_string");
File.WriteAllBytes(dirPath + imgName, imgByteArray);
That's it. Kindly up vote if you really find this solution works for you. Thanks in advance.
In a similar scenario what worked for me was the following:
byte[] bytes = Convert.FromBase64String(Base64String);
ImageTagId.ImageUrl = "data:image/jpeg;base64," + Convert.ToBase64String(bytes);
ImageTagId is the ID of the ASP image tag.
If you have a string of binary data which is Base64 encoded, you should be able to do the following:
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
You should be able to write the resulting array to a file.
public bool SaveBase64(string Dir, string FileName, string FileType, string Base64ImageString)
{
try
{
string folder = System.Web.HttpContext.Current.Server.MapPath("~/") + Dir;
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string filePath = folder + "/" + FileName + "." + FileType;
File.WriteAllBytes(filePath, Convert.FromBase64String(Base64ImageString));
return true;
}
catch
{
return false;
}
}
Using MemoryStream is not a good idea and violates a specification in MSDN for Image.FromStream(), where it says
You must keep the stream open for the lifetime of the Image.
A better solution is using ImageConverter, e.g:
public Image ConvertBase64ToImage(string base64)
=> (Bitmap)new ImageConverter().ConvertFrom(Convert.FromBase64String(base64));
In NetCore 6.0, you can use HttpClient and the async methods in the new File class.
The implementation is very simple:
static async Task DownloadFile(string imageUrl, string pathToSave)
{
var content = await GetUrlContent(url);
if (content != null)
{
await File.WriteAllBytesAsync(pathToSave, content);
}
}
static async Task<byte[]?> GetUrlContent(string url)
{
using (var client = new HttpClient())
using (var result = await client.GetAsync(url))
return result.IsSuccessStatusCode ? await result.Content.ReadAsByteArrayAsync():null;
}
Usage:
await DownloadFile("https://example.com/image.jpg", #"c:\temp\image.jpg");

Categories