Save as new name each time - c#

I can save a screenshot on a timer, but how could I have it save as a new name and not overwrite every time?
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(#"c:tempscreenshot.bmp", ImageFormat.Bmp);

You can use the handy method: Path.GetRandomFileName()
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save("c://" + Path.GetRandomFileName() + ".bmp", ImageFormat.Bmp);

You just need to generate a unique name every time. There are several possibilities. One would be to add a datetime-string at the end:
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(#"c:tempscreenshot" + DateTime.Now.Ticks + ".bmp", ImageFormat.Bmp);

Use an integer (or some other numeric type) and increment it within your timer. Then call your save method with something like:
bitmap.Save(string.Format("c:tempscreenshot.{0}.bmp", counter), ImageFormat.Bmp);
or use a GUID:
bitmap.Save(string.Format("c:tempscreenshot.{0}.bmp", Guid.NewGuid().ToString("N")), ImageFormat.Bmp);

You can generate a new filename everytime based on the current time. Something like this:
string GenerateFilename() {
string file = DateTime.Now.ToString("yy.MM.dd HH.mm.ss") + ".bmp";
return #"C:\" + file;
}
The good thing about using this approach is that when you browse the folder where you're saving the files, they will be sorted.
and then use it in your existing code:
bitmap.Save(GenerateFilename(), ImageFormat.Bmp);
You can also prepend any text (like image- or something) to the filename.
Another option would be append an integer to the end of the filename, like some copy handling programs do.

There is already something for that: Path.GetTempFileName()

Related

How to save image as stream?

I am trying to create a screenshot and send it from C# to PHP where I store it.
I create a screenshot like this:
Bitmap screenshot = TakeScreenshot();
Now I try to save it as a stream:
Stream myStream;
screenshot.Save(myStream, System.Drawing.Imaging.ImageFormat.Gif);
However, I get Use of unassigned local variable 'myStream'.
What am I doing wrong?
Functions:
private Bitmap TakeScreenshot()
{
//Create a new bitmap.
var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Create a graphics object from the bitmap.
using (var gfxScreenshot = Graphics.FromImage(bmpScreenshot))
{
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
Screen.PrimaryScreen.Bounds.Y,
0,
0,
Screen.PrimaryScreen.Bounds.Size,
CopyPixelOperation.SourceCopy);
}
return bmpScreenshot;
}
You have to initialize your stream before using it.
using (MemoryStream myStream = new MemoryStream()) {
screenshot.Save(myStream, System.Drawing.Imaging.ImageFormat.Gif);
}
By Stream you mean FileStream, MemoryStream, what? Whatever the case, just initialize the variable to be the proper kind of stream you need.
For example:
using(var myStream = new MemoryStream())
{....}

File already in used by another process. while saving file

I have document processor that extract thumbnails and Large images from tiff file.
But i get "file already in use" and "A generic error occurred in GDI+" error most frequently.
There three basic functions:
Get tiff pages count
Get all thumbnails
Get all large images
The file stream is used in all three operations.
Is there any way that I can use the file stream once, save a copy of the file in memory and release the file for other use.
I tried this:
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
{
photo = Image.FromStream(fs, true, false);
fs.Flush();
fs.Close();
}
using (photo)
{
//dummy hight and width passed to function.
generateThumbNails(photo,1,90,90);
System.Drawing.Imaging.FrameDimension dimention = new FrameDimension(photo.FrameDimensionsList[0]);
total = photo.GetFrameCount(dimention);
photo.Dispose();
}
generateThumbNails function:
public static Bitmap GenerateThumbNails(System.Drawing.Image img, int curPageNo, int width, int height)
{
System.Drawing.Imaging.FrameDimension dimention = new FrameDimension(img.FrameDimensionsList[0]);
img.SelectActiveFrame(dimention, curPageNo);
Bitmap bmp = new Bitmap(width, height);
Graphics g = Graphics.FromImage(bmp);
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.DrawImage(img, 0, 0, width, height);
g.Dispose();
return bmp;
}
But I get "A generic error occurred in GDI+" while re-sizing the image on the following line:
g.DrawImage(img, 0, 0, width, height);

Save print screen in C#

Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(#"C:\Temp\printscreen.jpg", ImageFormat.Jpeg);
This is my code for print screen button. The problem is that I press the button few times and it just write over the old image file (printscreen.jpg), it will not create another new image file such as printscreen1.jpg.
Try this. It will generate a unique file each time.
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
bitmap.Save(#"C:\Temp\printscreen"+Guid.NewGuid()+".jpg", ImageFormat.Jpeg);
OR
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(bitmap as Image);
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
var date = DateTime.Now.ToString("MMddyyHmmss");
bitmap.Save(#"C:\Temp\printscreen"+date+".jpg", ImageFormat.Jpeg);
it will not create another new image file
You are not asking it to create one, your code
bitmap.Save(#"C:\Temp\printscreen.jpg", ImageFormat.Jpeg);
is always writing to the same file.
new image file such as printscreen1.jpg
If you want to create a new file, you need to generate your filename dynamically. Something like
string fileName = System.IO.Path.GetTempPath() + DateTime.Now.ToString() + ".jpg";
bitmap.Save(fileName, ImageFormat.Jpeg);
You could count how many files already exist in the directory that start with printscreen.
int count = Directory.EnumerateFiles(#"C:\Temp\").Where(x => x.StartsWith("printscreen")).Count();
bitmap.Save(String.Format(#"C:\Temp\printscreen{0}.jpg", count), ImageFormat.Jpeg);
This might be slower if you have a lot of files since it has to iterate through them but it's more automated.
Another option would be to create a file that stores the current counter number.
File.Write("Counter.txt", counter.ToString());
Then when you want to start the counter after your program restarts, you can do this.
int counter = 0;
if(File.Exists("Counter.txt"))
counter = Int32.Parse(File.ReadAllText("Counter.txt"));
bitmap.Save(String.Format(#"C:\Temp\printscreen{0}.jpg", ++counter), ImageFormat.Jpeg);
Of course, if you don't plan on restarting the app and continuing the sequence, you can avoid the storing of the counter in a text file and just increment the counter from zero.
Create a field say counter and increment it on every button click and use it for file name -
bitmap.Save(#"C:\Temp\printscreen" + (counter++) + ".jpg", ImageFormat.Jpeg);
You can also try like this:
int number;
string[] path = Directory.GetFiles(#"C:\Temp\", #"PrintScreen*");
if (path.Length == 0)
{ bitmap.Save(#"C:\Temp\printscreen.jpg", ImageFormat.Jpeg); return; }
Array.Sort(path);
Array.Reverse(path);
int.TryParse(Regex.Match(path[0], #"(\d+)(?=\.jpg)").ToString(), out number);
bitmap.Save(#"C:\Temp\printscreen" + (number + 1).ToString() + ".jpg", ImageFormat.Jpeg);
I think it would be more efficient to pick the last file by sorting it in descending order rather than enumerating over them. Also, no need to keep track of separate counter pick the last count and increment it.
{
//Application.DoEvents();
Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(printscreen as Image);
graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);
string path = "";
if (forLog)
{
path = LoggerPath + StudentNumber.ToString() + "\\" + SessionID.ToString() + "\\";
}
else
{
path = PrintScreenPath + StudentNumber.ToString() + "\\" + SessionID.ToString() + "\\";
}
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
string fileName = DateTime.Now.Ticks.ToString();
SaveJPGWithCompressionSetting(printscreen, path + fileName + ".jpeg", 17L);
printscreen.Dispose();
graphics.Dispose();
return fileName;
}
And ere is SaveJPGWithCompressionSetting metHod
private void SaveJPGWithCompressionSetting(Image image, string szFileName, long lCompression)
{
try
{
EncoderParameters eps = new EncoderParameters(1);
eps.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, lCompression);
ImageCodecInfo ici = GetEncoderInfo("image/jpeg");
image.Save(szFileName, ici, eps);
}
}

How to save a Bitmap using filestream

I have created a bitmap and I want to save it in my upload folder. How can I do this?
My Code:
public FileResult image(string image)
{
var bitMapImage = new Bitmap(Server.MapPath("/Content/themes/base/images/photo.png"));
Graphics graphicImage = Graphics.FromImage(bitMapImage);
graphicImage.SmoothingMode = SmoothingMode.AntiAlias;
graphicImage.DrawString(image, new Font("Trebuchet MS,Trebuchet,Arial,sans-serif", 10, FontStyle.Bold), SystemBrushes.WindowFrame, new Point(15, 5));
graphicImage.DrawArc(new Pen(Color.Red, 3), 90, 235, 150, 50, 0, 360);
MemoryStream str = new MemoryStream();
bitMapImage.Save(str, ImageFormat.Png);
return File(str.ToArray(), "image/png");
}
The path I will use:
string mynewpath = Request.PhysicalApplicationPath + "Upload\\";
The Bitmap class has several overloads of the Save method. One of them takes a file name as parameter which means that you can use
bitMapImage.Save(mynewpath + "somefilename.png", ImageFormat.Png);
the question seems to be in conflict with your code (there you load a file from your images and return it) - anyway: there is a "Save" method on your Image-classes so just use this with the same Server.MapPath trick ... just make sure that the ASP.NET account has access/write rights for your target-folder:
string mynewpath = Request.PhysicalApplicationPath + "Upload\\myFile.png";
bitMapImage.Save(mynewpath);
remark: this is using your path but I don't know if this is really the right choice for your problem - as I said: MapPath should be the saver bet.

Saving Panel as an Image

I'm doing this paint application. It's kind of simple. It consist of a panel where I will draw on and then finally I will save as JPG or BMP or PNG file.
My application work perfectly but the problem I'm facing is that when I'm saving the output is not what drawn on the panel its black Image nothing just black.
all my work is been saved as
Thepic = new Bitmap(panel1.ClientRectangle.Width, this.ClientRectangle.Height);
and on the mouse (down,up thing) I have
snapshot = (Bitmap)tempDraw.Clone();
and it saved the work normally but again the rsult is black Image not what the panel contain.
I think the problem may be that you're using the "Clone" method.
Try "DrawToBitmap" - that's worked for me in the past.
Here's a sample that saves a bitmap from a control called "plotPrinter":
int width = plotPrinter.Size.Width;
int height = plotPrinter.Size.Height;
Bitmap bm = new Bitmap(width, height);
plotPrinter.DrawToBitmap(bm, new Rectangle(0, 0, width, height));
bm.Save(#"D:\TestDrawToBitmap.bmp", ImageFormat.Bmp);
Be aware of saving directly to the C directly as this is not
permitted with newer versions of window, try using SaveFileDialog.
SaveFileDialog sf = new SaveFileDialog();
sf.Filter = "Bitmap Image (.bmp)|*.bmp|Gif Image (.gif)|*.gif|JPEG Image (.jpeg)|*.jpeg|Png Image (.png)|*.png|Tiff Image (.tiff)|*.tiff|Wmf Image (.wmf)|*.wmf";
sf.ShowDialog();
var path = sf.FileName;
You could try this, this works for me.
I used MemoryStream.
MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, panel1.Width, panel1.Height));
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); //you could ave in BPM, PNG etc format.
byte[] Pic_arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(Pic_arr, 0, Pic_arr.Length);
ms.Close();

Categories