I've created a small demo, it includes uploading an image, creating a new one containing the uploaded image and some text.
It doesn't handle long text, so don't expect too much from this demo but it does give you the basics.
Here's the whole action.
public ActionResult Process(HttpPostedFileBase file, string text) { string error = string.Empty; //get file string filename = string.Empty; Stream filecontents = null; if ((file == null) || (file.ContentLength == 0)) error = "No file uploaded"; else { //get filename filename = file.FileName; filecontents = file.InputStream; } Bitmap uploadedImage = null; //check valid extensions if (!string.IsNullOrEmpty(filename)) { if (!validextensions.Contains(Path.GetExtension(filename))) error = "File is not an image"; else { //attempt to load image uploadedImage = new Bitmap(filecontents); } } //if there's an error, draw it on the image if (!string.IsNullOrEmpty(error)) { uploadedImage = new Bitmap(200, 200); var g = Graphics.FromImage(uploadedImage); g.DrawString(error, new Font("Arial", 8), new SolidBrush(Color.Red), new PointF(1, 1)); } //create new image Bitmap newimage = new Bitmap(400, 200); var graphics = Graphics.FromImage(newimage); //blend into image instead of overriding, this way we can use trasnparent PNGs instead of ignoring the transparency. graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver; //lets get the relative size so it will keep its ratio var width = 200; var height = 200; float ratio = (float)uploadedImage.Width / (float)uploadedImage.Height; if (ratio < 1) width = (int)(width * ratio); else height = (int)(height / ratio); //lets center the image var top = (200 - height) / 2; var left = (200 - width) / 2; //draw original file graphics.DrawImage(uploadedImage, new Rectangle(left, top, width, height)); //lets determine the size of the string; var sizeofString = graphics.MeasureString(text, new Font("Arial", 10)); //lets center the text var texttop = (200 - sizeofString.Height) / 2; var textleft = (200 - sizeofString.Width) / 2; //add text graphics.DrawString(text, new Font("Arial", 10), new SolidBrush(Color.Black), new PointF(textleft + 200, texttop)); //send to client Response.ContentType = "image/png"; newimage.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png); return new EmptyResult(); }
The code is self explanatory but we'll review it anyway.
1. First thing to take note of is the enctype="multipart/form-data" in the form element, it allows files to be uploaded.
2. Using the HttpPostedFileBase class to access the uploaded file.
3. Validating the file extensions.
4. If an error occured, we're drawing the error message on the image with DrawString.
5. Setting CompositingMode to SourceOver.
6. Calculating the relative maximum size and position for the uploaded image.
7. Drawing the uploaded image with DrawImage.
8. Mesuring the string size with MeasureString, so we can center it.
9. Setting the content type.
10. Saving the result Bitmap to the response stream with the selected ImageFormat.
11. Returning EmptyResult to stop MVC from processing this method.
You can find the demo project at:
https://github.com/drorgl/ForBlog/tree/master/ImageGenerator
Note: some code was written inefficiently for the sake of demo and ease of understanding, for example, CompositingMode and multiple creation of brushes and fonts.
0 comments:
Post a Comment