Asp. net mvc generate shrinkage graph to hard disk in real time

  • 2021-07-21 08:20:25
  • OfStack

For the processing of shrinkage chart, after the picture is uploaded to the server, two shrinkage charts of different sizes are generated synchronously for the front-end call, which can meet the demand at first. Slowly, with the diversification of front-end display, the shrinkage chart can no longer meet the demand of front-end display, so consider doing a real-time service of generating picture shrinkage chart.

It is a bit wasteful to generate shrinkage graph in real time every time it is called, so it is a bit wasteful to cache it to the hard disk at the same time of generating shrinkage, which improves the efficiency a lot.

I saw it on the Internet before. Someone used nginx + lua to achieve it. There is nothing to say about efficiency, but time is short and I don't have time to study it. Therefore, I will use aps. net mvc4 to achieve one for the time being, and then revise it slowly when I have time.

With their familiar. net performance may be less than 1 point, but the implementation speed is fast, which ensures that it can be online in extreme time and is more powerful in function.

The idea is very simple, that is, according to the request, judge whether the required shrinkage map already exists on the hard disk. If it is returned directly, if it is not, download the original map, generate the shrinkage map locally and return it to the client.

Paste the code snippet directly below:


/// <summary>
 ///  Generate a picture shrinkage map Action
 /// </summary>
 /// <param name="p"> Original picture url</param>
 /// <param name="id"> Picture size and the type of shrinkage map generated </param>
 /// <returns></returns>
 [ValidateInput(false)]
 public ActionResult Index(string p, string id)
 {
  if (string.IsNullOrEmpty(p))
  {
  return new HttpStatusCodeResult(404);
  }

  string oPath = Regex.Replace(p, @"http[s]?://(.*?)/", "/", RegexOptions.IgnoreCase);
  int? oWidth = 200, oHeight = 200;
  int cutMode = 3;
  string pPath;
  string oDir;

  if (!string.IsNullOrEmpty(id))
  {
  string[] ss = id.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
  if (ss.Length < 2)
  {
   return new HttpStatusCodeResult(404);
  }
  if (ss.Length > 2)
  {
   cutMode = int.Parse(ss[2]);
  }
  oPath = oPath.Insert(oPath.LastIndexOf('/') + 1, string.Format("{0}_{1}_{2}_", ss[0], ss[1], cutMode));
  oWidth = int.Parse(ss[0]);
  oHeight = int.Parse(ss[1]);
  }

  pPath = Server.MapPath(oPath);
  oDir = Path.GetDirectoryName(pPath);

  if (!System.IO.File.Exists(pPath))
  {
  byte[] imagebytes = FileHelper.DownLoadFile(p);
  if (!Directory.Exists(oDir))
  {
   Directory.CreateDirectory(oDir);
  }
  FileHelper.MakeThumbnail(FileHelper.BytToImg(imagebytes), oWidth.Value, oHeight.Value, (ThumbnailMode)cutMode, pPath, true);
  }

  return File(pPath, FileHelper.GetContentTypeByExtension(Path.GetExtension(pPath).ToLower()));
 }

Auxiliary methods:


 public class FileHelper
 {
  /// <summary>
 ///  Picture suffix and ContentType Corresponding dictionary 
 /// </summary>
 static Dictionary<string, string> extensionContentTypeDic;

 static FileHelper()
 {
  if (extensionContentTypeDic == null)
  {
  //.jpg", ".png", ".gif", ".jpeg
  extensionContentTypeDic = new Dictionary<string, string>();
  extensionContentTypeDic.Add(".jpg", "image/jpeg");
  extensionContentTypeDic.Add(".png", "image/png");
  extensionContentTypeDic.Add(".gif", "image/gif");
  extensionContentTypeDic.Add(".jpeg", "image/jpeg");
  }
 }
 /// <summary>
 ///  Gets from the suffix name extension
 /// </summary>
 /// <param name="extension"></param>
 /// <returns></returns>
 public static string GetContentTypeByExtension(string extension)
 {
  if (extensionContentTypeDic.ContainsKey(extension))
  {
  return extensionContentTypeDic[extension];
  }
  return null;
 }

 /// <summary > 
 ///  Will Image Object is converted to 2 Binary flow  
 /// </summary > 
 /// <param name="image" > </param > 
 /// <returns > </returns > 
 public static byte[] ImageToByteArray(Image image)
 {
  MemoryStream imageStream = new MemoryStream();
  Bitmap bmp = new Bitmap(image.Width, image.Height);
  Graphics g = Graphics.FromImage(bmp);
  g.DrawImage(image, new System.Drawing.Rectangle(0, 0, image.Width, image.Height));
  try
  {
  bmp.Save(imageStream, image.RawFormat);
  }
  catch (Exception e)
  {

  bmp.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
  }
  byte[] byteImg = imageStream.GetBuffer();
  bmp.Dispose();
  g.Dispose();
  imageStream.Close();
  return byteImg;
 }

 /// <summary> 
 ///  Byte stream into picture  
 /// </summary> 
 /// <param name="byt"> Byte stream to convert </param> 
 /// <returns> Converted Image Object </returns> 
 public static Image BytToImg(byte[] byt)
 {
  MemoryStream ms = new MemoryStream(byt);
  Image img = Image.FromStream(ms);
  ms.Close();
  return img;
 }

 /// <summary>
 ///  Generate shrinkage graph 
 /// </summary>
 /// <param name="originalImage"> Original picture Image</param>
 /// <param name="width"> Shrinkage width </param>
 /// <param name="height"> Shrinkage graph height </param>
 /// <param name="mode"> How to generate a shrinkage graph </param>
 /// <param name="thumbnailPath"> The address where the shrinkage chart is stored </param>
 public static Image MakeThumbnail(Image originalImage, int width, int height, ThumbnailMode mode, string thumbnailPath, bool isSave = true)
 {
  int towidth = width;
  int toheight = height;

  int x = 0;
  int y = 0;
  int ow = originalImage.Width;
  int oh = originalImage.Height;
  switch (mode)
  {
  case ThumbnailMode.HW:// Specify height-width scaling (possible deformation)    
   break;
  case ThumbnailMode.W:// Specify width and height in proportion    
   toheight = originalImage.Height * width / originalImage.Width;
   break;
  case ThumbnailMode.H:// Specify height and width in proportion  
   towidth = originalImage.Width * height / originalImage.Height;
   break;
  case ThumbnailMode.Cut:// Specify height and width trimming (no deformation)    
   if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
   {
   oh = originalImage.Height;
   ow = originalImage.Height * towidth / toheight;
   y = 0;
   x = (originalImage.Width - ow) / 2;
   }
   else
   {
   ow = originalImage.Width;
   oh = originalImage.Width * height / towidth;
   x = 0;
   y = (originalImage.Height - oh) / 2;
   }
   break;

  default:
   break;
  }

  // New 1 A bmp Picture  
  System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);
  // New 1 Sketchpad  
  Graphics g = System.Drawing.Graphics.FromImage(bitmap);
  // Set up high-quality interpolation method  
  g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
  // Set high quality , Smooth degree at low speed  
  g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
  // Empty the canvas and fill it with a transparent background color  
  g.Clear(Color.Transparent);
  // Draws the specified part of the original picture at the specified position and at the specified size  
  g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight),
  new Rectangle(x, y, ow, oh),
  GraphicsUnit.Pixel);
  if (!isSave)
  {
  return bitmap;
  }
  try
  {
  // With jpg Format to save thumbnails  
  //bitmap.Save(thumbnailPath, bitmap.RawFormat);
  bitmap.Save(thumbnailPath, ImageFormat.Jpeg);
  return bitmap;

  }
  catch (System.Exception e)
  {
  throw e;
  }
  finally
  {
  originalImage.Dispose();
  bitmap.Dispose();
  g.Dispose();
  }
  return null;
 }


 /// <summary>
 ///  Download the specified file 
 /// </summary>
 /// <param name="remoteUrl"></param>
 /// <param name="ss"></param>
 public static byte[] DownLoadFile(string remoteUrl)
 {
  WebClient wc = new WebClient();
  try
  {
  return wc.DownloadData(remoteUrl);
  }
  catch (Exception e)
  {
  throw new Exception(" Failed to download file ");
  }
 }

 }

 public enum ThumbnailMode
 {
 /// <summary>
 ///  Specify height-width scaling (possible deformation) 
 /// </summary>
 HW,
 /// <summary>
 ///  Specify height and width in proportion 
 /// </summary>
 H,
 /// <summary>
 ///  Specify width and height in proportion 
 /// </summary>
 W,
 /// <summary>
 ///  Specify height and width trimming (no deformation)  
 /// </summary>
 Cut,

 }

Access method:

http://www.souji8.com/Home/Index/{width}_{height}_{ThumMode}?p={imageUrl}

{imageUrl}: Destination picture address

{ThumMode}: 1: Specify width to scale, 2: Specify width to scale, 3: Specify width to trim (no deformation)

{Width}: Expected picture width

{Height}: Expect high picture

The above is the whole content of this paper, hoping to help everyone's study.


Related articles: