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.
Related
I am trying to save an image I've created from Bitmap in a given Path in my project, but I get this error: Additional information: A generic error occurred in GDI+.
This is the code :
public void SaveCaptchaImage(string name)
{
Bitmap image = new Bitmap(128, 64);
string path = "/content/images";
if (System.IO.File.Exists(path + name))
System.IO.File.Delete(path + name);
using (Pen myPen = new Pen(Color.Red, 5))
using (Brush myBrush = new SolidBrush(Color.Silver))
using (Font myFont = new Font("Arial", 16))
using (Graphics graphObject = Graphics.FromImage(image))
{
graphObject.FillRectangle(myBrush, new Rectangle(0, 0, 128, 64));
graphObject.DrawString(GetRandomCaptcha(), myFont, myBrush, new Point(20, 20));
image.Save(path + name + ".png", ImageFormat.Png);
}
image.Dispose();
}
The exception occurs at this line:
image.Save(path + name + ".png", ImageFormat.Png);
What can I do to solve this problem ?
Edit: I don't get why I got downvoted, but ok.
Wrap your path with Server.MapPath like:
image.Save(HttpContext.Current.Server.MapPath(Path.Combine(path, name + ".png")), ImageFormat.Png);
to get absolute path instead of relative.
and use Path.Combine method like #stuartd suggested in comments.
I am trying to use PDFsharp to insert a dynamically generated bitmap of a QR Code in to a PDF document. I don't want to save the bitmap to the file but just want to insert it into the PDF. The problem I'm having is the DrawImage command is looking for a string where the image file is located. But I don't want to save the file, I just want to insert it into the PDF document. Is there a way of doing this?
var QRCode_BMP = _generalCode.QR_CodeGenerator(AddReviewPath); //This generates the bitmap
MemoryStream streamQR = new MemoryStream();
QRCode_BMP.Save(streamQR, System.Drawing.Imaging.ImageFormat.Jpeg); //save bitmap into memory stream in jpeg format System.Drawing.Image QR_Jpeg = System.Drawing.Image.FromStream(streamQR);// save memory stream to image file
XImage xImage = XImage.FromGdiPlusImage(QR_Jpeg);
gfx = XGraphics.FromPdfPage(page);
DrawImage(gfx, xImage, 0, 0, 100, 100); //This is not working
QRCode_BMP.Dispose();
streamQR.Close();
gfx.Dispose();
You create a QR code in QRCode_BMP and then you create an XImage from QR_Jpeg and write it is not working.
QRCode_BMP is only used to create a stream that is never used. We don't see where QR_Jpeg is coming from.
Provide a complete sample.
BTW: You can use XImage.FromStream to use the stream you created.
P.S.: IMHO JPEG is a bad choice for QR codes. Just use BMP and PDFsharp will use a lossless compression.
This is how I made it work;
PdfDocument pdf = PdfGenerator.GeneratePdf("<b>some html here</b>", PageSize.A4);
QRCodeGenerator qrGenerator = new QRCodeGenerator();
QRCodeData qrCodeData = qrGenerator.CreateQrCode("some text here", QRCodeGenerator.ECCLevel.Q);
QRCode qrCode = new QRCode(qrCodeData);
Bitmap qrCodeImage = qrCode.GetGraphic(10);
PdfPage page = pdf.Pages[0]; //I will add it to 1st page
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
XImage image = XImage.FromGdiPlusImage(qrCodeImage); //you can use XImage.FromGdiPlusImage to get the bitmap object as image (not a stream)
gfx.DrawImage(image, 50, 50, 150, 150);
//save your pdf, dispose other objects
Using XImage.FromStream like #I liked the old Stack Overflow mentioned, in your posted code you should be able to just use:
var QRCode_BMP = _generalCode.QR_CodeGenerator(AddReviewPath); //This generates the bitmap
MemoryStream streamQR = new MemoryStream();
QRCode_BMP.Save(streamQR, System.Drawing.Imaging.ImageFormat.Jpeg); //save bitmap into memory stream in jpeg format System.Drawing.Image QR_Jpeg = System.Drawing.Image.FromStream(streamQR);// save memory stream to image file
//XImage xImage = XImage.FromGdiPlusImage(QR_Jpeg); // <-- Removed
gfx = XGraphics.FromPdfPage(page);
gfx.DrawImage(XImage.FromStream(streamQR), 0, 0, 100, 100); // <-- Added
//DrawImage(gfx, xImage, 0, 0, 100, 100); //This is not working // <-- Removed
QRCode_BMP.Dispose();
streamQR.Close();
gfx.Dispose();
For general usage of streams for XGraphics.DrawImage (library PDFSharp) here's some code I use to print SVG vector path data to PDF:
System.Windows.Shapes.Path path = new System.Windows.Shapes.Path();
// YouTube like button SVG vector path data:
path.Data = Geometry.Parse("M12.42,14A1.54,1.54,0,0,0,14,12.87l1-4.24C15.12,7.76,15,7,14,7H10l1.48-3.54A1.17,1.17,0,0,0,10.24,2a1.49,1.49,0,0,0-1.08.46L5,7H1v7ZM9.89,3.14A.48.48,0,0,1,10.24,3a.29.29,0,0,1,.23.09S9,6.61,9,6.61L8.46,8H14c0,.08-1,4.65-1,4.65a.58.58,0,0,1-.58.35H6V7.39ZM2,8H5v5H2Z");
// Visual check of the path:
// https://yqnn.github.io/svg-path-editor/
// Color area bordered through path of SVG vector:
path.Fill = new SolidColorBrush(Colors.Black);
// Upscale path, if final image is blurry:
double scale = 2;
path.RenderTransform = new ScaleTransform(scale, scale);
Rect bounds = path.Data.GetRenderBounds(null);
// Increase render bounds (here: "+ 4"), if parts of the path in the final image are cut off (test it with "scale = 1" before upscaling):
bounds.Width = (bounds.Width + 4) * scale;
bounds.Height = (bounds.Height + 4) * scale;
path.Measure(bounds.Size);
path.Arrange(bounds);
RenderTargetBitmap bitmap = new RenderTargetBitmap(
(int)bounds.Width, (int)bounds.Height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(path);
// Transparent areas are replaced with black pixels when using a "BmpBitmapEncoder", so instead use a "PngBitmapEncoder":
PngBitmapEncoder encoderPng = new PngBitmapEncoder();
encoderPng.Frames.Add(BitmapFrame.Create(bitmap));
using (MemoryStream stream = new MemoryStream())
{
encoderPng.Save(stream);
// Draw image to PDF using "XGraphics.DrawImage":
gfx.DrawImage(XImage.FromStream(stream), 10, 100, 14.05, 12.05);
}
i am using this code in my asp.net website. its barcode generation code.. problem this code is depend on (IDAutomationHC39M) this font. so on localhost i have installed this font in my fonts folder and code is working successfully in local. but i do not know how to install this on server
string barCode = Request.QueryString["id"].ToString();
System.Web.UI.WebControls.Image imgBarCode = new System.Web.UI.WebControls.Image();
using (Bitmap bitMap = new Bitmap(barCode.Length * 40, 80))
{
using (Graphics graphics = Graphics.FromImage(bitMap))
{
Font oFont = new Font("IDAutomationHC39M", 16);
PointF point = new PointF(2f, 2f);
SolidBrush blackBrush = new SolidBrush(Color.Black);
SolidBrush whiteBrush = new SolidBrush(Color.White);
graphics.FillRectangle(whiteBrush, 0, 0, bitMap.Width, bitMap.Height);
graphics.DrawString("*" + barCode + "*", oFont, blackBrush, point);
}
using (MemoryStream ms = new MemoryStream())
{
bitMap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] byteImage = ms.ToArray();
Convert.ToBase64String(byteImage);
imgBarCode.ImageUrl = "data:image/png;base64," + Convert.ToBase64String(byteImage);
}
plBarCode.Controls.Add(imgBarCode);
}
Assuming a web based font will not work (ie you need to render your barcode server side and possibly embed it with other graphics / images), you can take the following approach. I didn't write this code but have used it and it does work.
You will need to load your font from a resource or possibly via a URL. Then pass the bits to the following. If loading from a resource, google that as there are a fair number of examples.
You can also use fontCollection.AddFontFile() and simplify your code but that will require access to the local (on server) filesystem.
public FontFamily GetFontFamily(byte[] bytes)
{
FontFamily fontFamily = null;
var handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
try
{
var ptr = Marshal.UnsafeAddrOfPinnedArrayElement(bytes, 0);
var fontCollection = new PrivateFontCollection();
fontCollection.AddMemoryFont(ptr, bytes.Length);
fontFamily = fontCollection.Families[0];
}
finally
{
// don't forget to unpin the array!
handle.Free();
}
return fontFamily;
}
if you are developing for relatively modern browsers you can read up on #font-face
or, it may be just a simple matter of installing the font on your web server, typically you just need to copy the font file over to some folder on the server, say the desktop, and it should just be a simple matter of right clicking and selecting "install font"
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()
I want to write a small program in .NET 4.0 that will open a .jpg (or .jpeg) file, add a line of text to the image, and then resave the image as a .jpg. Does anyone know the easiest way to do this?
Thanks for any help.
Something like this:
var filePath = #"D:\Pictures\Backgrounds\abc.jpg";
Bitmap bitmap = null;
// Create from a stream so we don't keep a lock on the file.
using (var stream = File.OpenRead(filePath))
{
bitmap = (Bitmap)Bitmap.FromStream(stream);
}
using (bitmap)
using (var graphics = Graphics.FromImage(bitmap))
using (var font = new Font("Arial", 20, FontStyle.Regular))
{
// Do what you want using the Graphics object here.
graphics.DrawString("Hello World!", font, Brushes.Red, 0, 0);
// Important part!
bitmap.Save(filePath);
}
var myBitmap = new Bitmap("C:\\myImage.jpg");
var g = Graphics.FromImage(myBitmap);
g.DrawString("My\nText", new Font("Tahoma", 40), Brushes.White, new PointF(0, 0));