Dynamic image creation

I have three values ​​that are dynamically generated in the code for my web form. These three values ​​will be shown to the user. Although this may seem strange, I do NOT want the user to be able to copy and paste these values. Because of this, I would like to write values ​​through an image that will be dynamically plotted.

My question is, is there a way to dynamically create an image and write it back? I would prefer not to create the image, save it on the server, and then pass the URL to the page. I would really like to write binary content along with the answer. Is it possible? If so, can someone explain / show how?

+3
source share
3 answers

In a simplified form, you can use context.Response.BinaryWrite()to write an array of bytes to the response stream. Usually you call this from a custom HTTP handler that maps to a particular mime type - ie * .jpg or * .png, etc.

The following block of code shows one way to create a simple capcha image and returns it as an array of bytes that can be used context.Response.BinaryWrite()

private Byte[] GenerateImage()
{
  RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
  Byte[] rand = new Byte[200];
  rng.GetBytes(rand);
  int i = 0;

  Bitmap bmp = new Bitmap(_imageWidth, _imageHeight, PixelFormat.Format24bppRgb);
  Bitmap cloneBmp = null;
  Graphics g = null;
  LinearGradientBrush backgroundBrush = null;
  LinearGradientBrush textBrush = null;
  SolidBrush[] circleBrush = new SolidBrush[3];
  Font font = null;
  GraphicsPath path = null;

  try
  {
    g = Graphics.FromImage(bmp);
    g.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle r = new Rectangle(0, 0, _imageWidth, _imageHeight);
    backgroundBrush = new LinearGradientBrush(
            new RectangleF(0, 0, _imageWidth, _imageHeight),
            Color.FromArgb(rand[i++] / 2 + 128, rand[i++] / 2 + 128, 255),
            Color.FromArgb(255, rand[i++] / 2 + 128, rand[i++] / 2 + 128),
            rand[i++] * 360 / 256);
    g.FillRectangle(backgroundBrush, r);

    for (int br = 0; br < circleBrush.Length; br++)
    {
      circleBrush[br] = new SolidBrush(Color.FromArgb(128, rand[i++], rand[i++], rand[i++]));
    }

    for (int circle = 0; circle < 30; circle++)
    {
      int radius = rand[i++] % 10;
      g.FillEllipse(circleBrush[circle % 2],
          rand[i++] * _imageWidth / 256,
          rand[i++] * _imageHeight / 256,
          radius, radius);
    }

    font = new Font("Tahoma", _imageHeight / 2, FontStyle.Regular);
    StringFormat format = new StringFormat();
    format.Alignment = StringAlignment.Center;
    format.LineAlignment = StringAlignment.Center;

    path = new GraphicsPath();
    path.AddString(_challengeKey, font.FontFamily, (int)font.Style, font.Size, r, format);

    textBrush = new LinearGradientBrush(
            new RectangleF(0, 0, _imageWidth, _imageHeight),
            Color.FromArgb(rand[i] % 128, rand[i] % 128, rand[i++] % 128),
            Color.FromArgb(rand[i] % 128, rand[i] % 128, rand[i++] % 128),
            rand[i++] * 360 / 256);
    g.FillPath(textBrush, path);

    cloneBmp = (Bitmap)bmp.Clone();

    int distortionSeed = rand[i++];
    double distortion = distortionSeed > 128 ? 5 + (distortionSeed - 128) % 5 : -5 - distortionSeed % 5;
    for (int y = 0; y < _imageHeight; y++)
    {
      for (int x = 0; x < _imageWidth; x++)
      {
        // Adds a simple wave
        int newX = (int)(x + (distortion * Math.Sin(Math.PI * y / 96.0)));
        int newY = (int)(y + (distortion * Math.Cos(Math.PI * x / 64.0)));
        if (newX < 0 || newX >= _imageWidth)
        {
          newX = 0;
        }
        if (newY < 0 || newY >= _imageHeight)
        {
          newY = 0;
        }
        bmp.SetPixel(x, y, cloneBmp.GetPixel(newX, newY));
      }
    }

    MemoryStream stream = new MemoryStream();
    bmp.Save(stream, ImageFormat.Jpeg);
    return stream.ToArray();
  }
  finally
  {
    if (backgroundBrush != null)
    {
      backgroundBrush.Dispose();
    }
    if (textBrush != null)
    {
      textBrush.Dispose();
    }
    for (int br = 0; br < circleBrush.Length; br++)
    {
      if (circleBrush[br] != null)
      {
        circleBrush[br].Dispose();
      }
    }
    if (font != null)
    {
      font.Dispose();
    }
    if (path != null)
    {
      path.Dispose();
    }
    if (g != null)
    {
      g.Dispose();
    }
    if (bmp != null)
    {
      bmp.Dispose();
    }
    if (cloneBmp != null)
    {
      cloneBmp.Dispose();
    }
  }
}

Here is what your http handler might look like. Note that this is very simple and will do the job, but does not include image caching code for the client or server side that you want to ultimately add to the performance.

 public class ImageHandler : IHttpHandler
  {
    public bool IsReusable
    {
      get
      {
        return true;
      }
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = MimeTypeConstants.JPG;
        context.Response.Clear();
        context.Response.BinaryWrite(GenerateImage());
        context.Response.End();
    }
  }

Enjoy it!

+3
source

, URI ( ) ).

0

Yes, it's pretty easy to create an image from text:

http://chiragrdarji.wordpress.com/2008/05/09/generate-image-from-text-using-c-or-convert-text-in-to-image-using-c/

Use a shared handler file (.ashx) to display the image. Then go to the handler from your page .. and it will be displayed as an image.

0
source

Source: https://habr.com/ru/post/1751437/


All Articles