C# Path.GetTempFileName() with specific path - c#

I'm creating a temp file and get its path with this code:
public ActionResult Comp(string Link)
{
var sv = Server.MapPath(Link);
int quality = 45;
string tempFile = Path.GetTempFileName();
System.IO.File.Copy(sv, tempFile, true);
using (var myBitmap = Image.FromFile(tempFile))
{
ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/jpeg");
Encoder myEncoder = Encoder.Quality;
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, quality);
EncoderParameters myEncoderParameters = new EncoderParameters(1);
myEncoderParameters.Param[0] = myEncoderParameter;
myBitmap.Save(sv, myImageCodecInfo, myEncoderParameters);
}
System.IO.File.Delete(tempFile);
return RedirectToAction("Index");
}
private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
int j;
ImageCodecInfo[] encoders;
encoders = ImageCodecInfo.GetImageEncoders();
for (j = 0; j < encoders.Length; ++j)
{
if (encoders[j].MimeType == mimeType)
return encoders[j];
}
return null;
}
The Comp function using in image compressor. It get string file path, creating a tmp file in C:\Users\User1\AppData\Local\Temp by getted image in Link, nextly encodede tmp file with setted quality and set tmp file to getted image, finally deleting tmp file. But this code create and delete a temp file in C:\Users\User1\AppData\Local\Temp. I want to create temp file in a specific path because my server not get permission this path. So this code may be as follow:
string tempFile = Path.GetTempFileName("/Content/temp/");
//It gets error that do not have overload method of GetTempFileName

If the problem is that the code does not have permissions in the temp folder, how about simply creating a unique file name in a folder the code does have permissions to? The function Path.GetRandomFileName() will do so. It does not create the file for you, it just create a random file name that you can use in a folder of your choice. To be extra safe, you can first check if the file already exists, but that will be highly unlikely.
Example:
String folderPathThatYouCanWriteTo = "Your Writable Path here";
String fullFilePath = null;
do
{
fullFilePath = String.Format(#"{0}\{1}", folderPathThatYouCanWriteTo, Path.GetRandomFileName());
} while (File.Exists(fullFilePath));
//Now you can use fullFilePath
etc.

Related

Create Zip file for multiple images c#

In my requirement I am converting docx to images its working fine but I need to store that converted multiple images into Zip file. Zip file was created successfully but Images are not opening it show corrupted/damage. Please try to help me to solve this solution. please refer my below total code. I used using Ionic.Zip; for creating a zip file.
//Opens the word document and fetch each page and converts to image
foreach (Microsoft.Office.Interop.Word.Window window in doc1.Windows)
{
foreach (Microsoft.Office.Interop.Word.Pane pane in window.Panes)
{
using (var zip = new ZipFile())
{
var pngTarget = "";
for (var i = 1; i <= pane.Pages.Count; i++)
{
var page = pane.Pages[i];
var bits = page.EnhMetaFileBits;
var target = Path.Combine(startupPath.Split('.')[0], string.Format("{1}_page_{0}", i, startupPath.Split('.')[0]));
try
{
using (var ms = new MemoryStream((byte[])(bits)))
{
var image = System.Drawing.Image.FromStream(ms);
pngTarget = Path.ChangeExtension(target, "png");
image.Save(pngTarget, ImageFormat.Png);
zip.AddEntry(pngTarget, "Img");
}
}
catch (System.Exception ex)
{ }
}
// CREATE A FILE USING A STRING.
// THE FILE WILL BE STORED INSIDE THE ZIP FILE.
// ZIP THE FOLDER WITH THE FILES IN IT.
//zip.AddFiles(Directory.GetFiles(#"c:\\users\\chaitanya_t\\Downloads\\"), "Images");
zip.Save(#"c:\\users\\chaitanya_t\\Downloads\\encoded.zip"); // SAVE THE ZIP FILE.
}
}
}
Try setting the stream position at the begin of the stream before processing:
using (var ms = new MemoryStream((byte[])(bits))){
ms.Position = 0; // Set stream position at the begin of the stream
var image = System.Drawing.Image.FromStream(ms);
pngTarget = Path.ChangeExtension(target, "png");
image.Save(pngTarget, ImageFormat.Png);
zip.AddEntry(pngTarget, ms.ToArray());
}

C# Generic Error GDI+ on SaveAdd

I'm trying to create a small program to take a set of multi-page TIFF files from a folder, remove the front page and save the remaining pages using the same name to a separate output folder.
The files can save to the output folder without issue but I get "A Generic Error Occurred in GDI+" when it gets to the SaveAdd function on the second document. The first document(7 pages on output) adds all pages correctly. The second document fails when trying to add additional pages/frames after the initial page. I've tried different documents as first and second with varying number of pages. Can anyone shed any light on the issue?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace FrontPageRemover
{
class Program
{
static void Main(string[] args)
{
Image frame;
int pages;
string fileName;
string folderPath = #"TIFF\Tiff Files";
string[] files = Directory.GetFiles(folderPath);
Image image;
Encoder encoder = Encoder.SaveFlag;
ImageCodecInfo encoderInfo = ImageCodecInfo.GetImageEncoders().First(i => i.MimeType == "image/tiff");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
foreach (string file in files)
{
image = Image.FromFile(file);
pages = image.GetFrameCount(FrameDimension.Page);
image.SelectActiveFrame(FrameDimension.Page, 1);
fileName = Path.GetFileName(file);
image.Save(#"TIFF\Files Out\" + fileName, encoderInfo, encoderParams);
for (int index = 2; index < pages; index++)
{
image.SelectActiveFrame(FrameDimension.Page, index);
encoderParams.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.FrameDimensionPage);
image.SaveAdd(encoderParams);
}
encoderParams.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.Flush);
image.SaveAdd(encoderParams);
image.Dispose();
}
}
}
}
Comments pointed me in the right direction with regards to the EncoderParameters not updating/being disposed of correctly.
The issue was with
encoderParams.Param[0] = new EncoderParameter(encoder, (long)EncoderValue.MultiFrame);
being outside of the loop. Hence the first document working correctly but the second document failing.

How to convert ImageCodecInfo to byte[] or Stream

I want to upload an optimized images to Amazon.
So that I have found this article that explains how to optimize an image with a compression level.
The problem is that this example saves the image to disk and I need to save it to Amazon storage.
I have this code:
public static ImageCodecInfo OptimizeImage(Image image, string fileName, long compression, string type)
{
var encoderParams = new EncoderParameters(1)
{
Param = {[0] = new EncoderParameter(Encoder.Quality, compression)}
};
return GetEncoderInfo(type);
}
private static ImageCodecInfo GetEncoderInfo(string mime_type)
{
ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
for (int i = 0; i <= encoders.Length; i++)
{
if (encoders[i].MimeType == mime_type)
return encoders[i];
}
return null;
}
I should have a Stream or byte[] object in order to send it to the UploadImageToAmazon method as parameter.
So, I have an Image object and its ImageCodecInfo, how can I convert it to Stream or to byte[]?
Or if you could suggest me how to optimize images and upload them into amazon would be also good.
Thanks.
You can save an Image object to a Stream with Image.Save Method (Stream, ImageFormat)
Edit :
If I recap with the code provided in the example you linked:
private void SaveJpg(Image image, string file_name, long compression)
{
try
{
EncoderParameters encoder_params = new EncoderParameters(1);
encoder_params.Param[0] = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, compression);
ImageCodecInfo image_codec_info =
GetEncoderInfo("image/jpeg");
File.Delete(file_name);
using(var imageStream = new Stream()){
// save to stream
image.Save(imageStream, image_codec_info, encoder_params);
// upload
UploadImageToAmazon(imageStream);
}
}
catch (Exception ex)
{
MessageBox.Show("Error saving file '" + file_name +
"'\nTry a different file name.\n" + ex.Message,
"Save Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}

HttpPostedFileBase File because it is being used by another process

i have use a controller action with use of file uploader and i want to compress the image and compress process perform after save the image, so my problem is : i want save only compress image and delete the orignal one. but this code shows error : file because it is being used by another process
My Code is :
public ActionResult submitgeneralinfo(HttpPostedFileBase file, int? EmployeeId, GeneralInfoViewModel model)
{
var ext = Path.GetExtension(file.FileName);
uniquefilename = Convert.ToString(ID) + ext;
var path = Path.Combine(Server.MapPath("~/Attachements/GeneralInfodp/"), uniquefilename);
var compaths = Path.Combine(Server.MapPath("~/Attachements/GeneralInfodp/"), "com" + uniquefilename);
file.SaveAs(path);
file.InputStream.Dispose();
CompressImage(Image.FromFile(path), 30, compaths);
file.InputStream.Close();
file.InputStream.Dispose();
GC.Collect();
FileInfo file3 = new FileInfo(path);
if (file3.Exists)
{
file3.Delete(); // error :- file because it is being used by another process
}
}
private void CompressImage(Image sourceImage, int imageQuality, string savePath)
{
try
{
//Create an ImageCodecInfo-object for the codec information
ImageCodecInfo jpegCodec = null;
//Set quality factor for compression
EncoderParameter imageQualitysParameter = new EncoderParameter(
System.Drawing.Imaging.Encoder.Quality, imageQuality);
//List all avaible codecs (system wide)
ImageCodecInfo[] alleCodecs = ImageCodecInfo.GetImageEncoders();
EncoderParameters codecParameter = new EncoderParameters(1);
codecParameter.Param[0] = imageQualitysParameter;
//Find and choose JPEG codec
for (int i = 0; i < alleCodecs.Length; i++)
{
if (alleCodecs[i].MimeType == "image/jpeg")
{
jpegCodec = alleCodecs[i];
break;
}
}
//Save compressed image
sourceImage.Save(savePath, jpegCodec, codecParameter);
}
catch (Exception e)
{
}
}
Save image direct in low size with using WebImage
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
WebImage img = new WebImage(file.InputStream);
if (img.Width > 1000)
img.Resize(1000, 1000);
img.Save("path");
return View();
}

Invalid Parameter Error when calling System.Drawing.Image.Save

i am getting Invalid Parameter Error when calling System.Drawing.Image.Save function.
i google and found a few suggestions but nothing works.
what i am trying to do is that, when i upload an image and if it's lager than 100kb i would like to reduce the image size to half. please help.
System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(realpath);
FullsizeImage = System.Drawing.Image.FromFile(realpath);
int fileSize = (int)new System.IO.FileInfo(realpath).Length;
while (fileSize > 100000) //If Larger than 100KB
{
SaveJpeg(realpath, FullsizeImage);
fileSize = (int)new System.IO.FileInfo(realpath).Length;
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
public static void SaveJpeg(string path, Image img)
{
Image NewImage = img;
img.Dispose();
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, 85L);
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
ImageCodecInfo jpegCodec = GetEncoderInfo(GetMimeType(path.Substring(path.LastIndexOf('.'), path.Length - path.LastIndexOf('.'))));
//THE ERROR IS HERE!!!!!!
NewImage.Save(path, jpegCodec, encoderParams);
//THE ERROR IS HERE!!!!!!
}
public static string GetMimeType(string extension)
{
if (extension == null)
{
throw new ArgumentNullException("extension");
}
if (!extension.StartsWith("."))
{
extension = "." + extension;
}
switch (extension.ToLower())
{
#region Big freaking list of mime types
// combination of values from Windows 7 Registry and
// from C:\Windows\System32\inetsrv\config\applicationHost.config
// some added, including .7z and .dat
case ".323": return "text/h323";
// more extension here..
#endregion
default:
// if you have logging, log: "No mime type is registered for extension: " + extension);
return "application/octet-stream";
}
}
EDIT : I modified the code as below, now the image is saving without any exception! Thanks! but another problem here. the file size is not getting reduced. which mean my while loop can never exit. please help and thanks again.
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(realpath)))
{
using (Image FullsizeImage = Image.FromStream(ms))
{
//code here
int fileSize = (int)new System.IO.FileInfo(realpath).Length;
while (fileSize > 100000) //If Larger than 100KB
{
SaveJpeg(realpath, FullsizeImage, 85L);
fileSize = (int)new System.IO.FileInfo(realpath).Length;
}
}
}
Can someone help me please, my problem is not solved yet :(
Because you're disposing an image object.
public static void SaveJpeg(string path, Image img)
{
Image NewImage = img;
img.Dispose(); <------- Here
...
}
EDIT: Method Image.FromFile file opens a stream and that file wont be closed till your method is not terminated. Try to use MemoryStream.
using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(realPath)))
{
using (Image img = Image.FromStream(ms))
{
ImageCodecInfo myImageCodecInfo;
Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
myImageCodecInfo = GetEncoderInfo("image/jpeg");
myEncoder = Encoder.Quality;
myEncoderParameters = new EncoderParameters(1);
myEncoderParameter = new EncoderParameter(myEncoder, 85L);
myEncoderParameters.Param[0] = myEncoderParameter;
img.Save(realPath, myImageCodecInfo, myEncoderParameters);
}
}

Categories

Resources