Showing posts with label Image Handling. Show all posts
Showing posts with label Image Handling. Show all posts

Wednesday, November 3, 2010

Generate captcha image in asp.net - simple way

When it comes to captcha images simple question pops in i.e. how to generate captcha images?
This article is about generating Captcha image in asp.net, this is very simple logic which can be implemented immediately for any website. You can directly Download Demo and use it.
We have used following simple steps to Generate Captcha Image in asp.net
  1. Create Captcha Image from random numbers and store that number in session variable, we have used Captcha.aspx page for the same.
  2. Use Captcha.aspx as source for the captcha image in Default.aspx page, i.e. for image tag give Captcha.aspx as SRC.
  3. On Submit click simply verify captcha entered by user and captcha in session. 
Our folder structure is very simple, check out following image


To understand the way we have checked captcha, have look on HTML of Default.aspx page (Check out DemoCode, for better understanding.)


Catptcha Text



Check out the way we have used Captcha.aspx page in image source.

On submit click we simply checks whether Captcha entered in "txtCaptcha" is valid or not, we have following code for submit button clicked.

protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (Session["Captcha"] != null)
        {
            if (txtCaptcha.Text == Session["Captcha"].ToString())
            {
                Response.Redirect("RedirectPage.aspx");
            }
            else
            {
                Response.Write("Please Enter Valid Captcha code");
                txtCaptcha.Text = "";
            }
        }
        else
        {
            Response.Write("Session Expired, please re-enter Captcha.");
        }
    }

Now what remains is the logic for Generate captcha image, we don't have any HTML tags on captcha.aspx, we simply write following code for Binary Image Generation and write it. We have used Random number; but we can have our different logic for the same.

protected void Page_Load(object sender, EventArgs e)
    {
        Response.ContentType = "text/plain";
        Random random = new Random(DateTime.Now.Millisecond);

        int number = random.Next(100000);

        Session.Add("Captcha",number.ToString());

        System.Drawing.Bitmap bmpOut = new Bitmap(100, 50);

        Graphics graphics = Graphics.FromImage(bmpOut);

        graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Bilinear;

        graphics.FillRectangle(Brushes.Aquamarine, 0, 0, 100, 50);

        graphics.DrawString(number.ToString(), new Font("TimesNewRoman", 20), new SolidBrush(Color.Coral), 0, 0);

        MemoryStream memorystream = new MemoryStream();

        bmpOut.Save(memorystream, System.Drawing.Imaging.ImageFormat.Png);

        byte[] bmpBytes = memorystream.GetBuffer();

        bmpOut.Dispose();

        memorystream.Close();

        Response.BinaryWrite(bmpBytes);

        Response.End();

    }

Thats it we are done with our Generate captcha image in asp.net. Very simple code to use, download democode and use it directly in your web application.

Download Democode here---> CaptchaInAsp.net.zip Submit this story to DotNetKicks

Read more...

Sunday, October 10, 2010

Image Handling in Asp.net

This article discuss about Image Handling, which in turns become important while handling high resolution images and displaying them in different sizes. Especially in case of E-commerce web applications, where admin can add different images of the same product so that users can get feel of the products. Also for image galleries where we need display same image in different sizes with zoom in and zoom out options.
For above requirement following points should be considered
  • Image should not distorted when re-sized.
  • Quality of the image should remain same.
  • If image is of High resolution then while displaying image is different sizes; the image which loads in browser should be of relative size. E.g. suppose image resolution is of 2736x3648, and we resize such high resolution image in the size of 200x300, then the new small image should be of relative size, i.e. original image size is 3.34MB then while displaying in small size it should be reduced as per size.
  • All images displayed in browser should be of same time, i.e. user can upload images like JPEG, JPG, BMP, TIFF etc. and while displaying all images should be displayed in PNG format only.
  • End user should be able save image of size which he/she is able to see in browser. i.e. if browser is showing image with 200x300 size; user can save image by right clicking it, then the image which is getting saved should be of the 200x300 size only.
Download DemoCode for better understanding of this article, you can also get to debug code while reading the article.
The main file for all above operations is ImageHandler.ashx, its a http handler file, in that file following function takes care of resizing of image, just check it out.
private Image ResizeImage(Image img, int maxWidth, int maxHeight)
    {
        if (img.Height < maxHeight && img.Width < maxWidth) return img;
        Double xRatio = (double)img.Width / maxWidth;
        Double yRatio = (double)img.Height / maxHeight;
        Double ratio = Math.Max(xRatio, yRatio);
        int NewX = (int)Math.Floor(img.Width / ratio);
        int NewY = (int)Math.Floor(img.Height / ratio);
        Bitmap imgCopy = new Bitmap(NewX, NewY, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        Graphics graphicsImg = Graphics.FromImage(imgCopy);
        graphicsImg.Clear(Color.Transparent);
        graphicsImg.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        //HighQualityBicubic gives best quality when resizing images
        graphicsImg.DrawImage(img,
            new Rectangle(0, 0, NewX, NewY),
            new Rectangle(0, 0, img.Width, img.Height),
            GraphicsUnit.Pixel);
        graphicsImg.Dispose();
        img.Dispose();
        return imgCopy;
    }
Above function takes care of re-sizing of image, this function simply maintains the quality of image, and if image which we are re-sizing is less than in size than that we are asking for, this function simply returns the image. To avoid distortion of image on re-sizing we have maintained aspect ratio too.
We are using ashx file as query string in Image source, which picks up image and render it in desired size code is as below.

So remaining code of our Ashx file is as below
string sImageFileName = "";
    string imageSize = "";
    int oldHeight, oldWidth, NewHeight, NewWidth;

    System.Drawing.Image objImage;
    
    public void ProcessRequest (HttpContext context)
    {
        sImageFileName = context.Request.QueryString["img"];
        imageSize = Convert.ToString(context.Request.QueryString["sz"]);

        if (imageSize == "Small") NewHeight = 50;
        else if (imageSize == "Thumb") NewHeight = 160;
        else if (imageSize == "Medium") NewHeight = 320;
        else if (imageSize == "Large") NewHeight = 640;
        
        objImage = System.Drawing.Bitmap.FromFile(System.Web.HttpContext.Current.Server.MapPath("Images//" + sImageFileName));

        oldHeight = objImage.Height;
        oldWidth = objImage.Width;
        NewWidth = oldWidth * (NewHeight / oldHeight);

        objImage = ResizeImage(objImage, oldHeight, NewHeight);

        MemoryStream objMemoryStream = new MemoryStream();
        objImage.Save(objMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
        byte[] imageContent = new byte[objMemoryStream.Length];
        objMemoryStream.Position = 0;
        objMemoryStream.Read(imageContent, 0, (int)objMemoryStream.Length);

        context.Response.BinaryWrite(imageContent);
    }
 
    public bool IsReusable
    {
        get 
        {
            return false;
        }
    }

 
    private bool callback()
    {
        return true;
    }

We have developed logic for image handling in mainly two files one is web user control i.e. webImageGallery.ascx and another is ImageHandler.ashx.
Check out folder structure of the democode.
Following Html code of imgGallery.ascx is, do refer democode.
We have one function in imgGallery.ascx.cs file, which builds gallery kind of logic is named CreateImages(), and its code is as below, you can put your own logic for creating image gallery the way you want, I tired to keep logic simple. Once you build do solution check out source code of the gallery. Its simple JavaScript which changes image source on click on thumb image.
protected void CreateImages()
    {
        int Count = 0;
        HtmlTableRow _htmlTableRow = new HtmlTableRow();
        _ProductTable.Rows.Add(_htmlTableRow);

        Directory.SetCurrentDirectory(imagePath);

        for (Count = 1; Count <= imageCount; Count++)
        {
            HtmlTableCell _htmlTableTd = new HtmlTableCell();
            _htmlTableRow.Cells.Add(_htmlTableTd);
            _htmlTableTd.Align = Convert.ToString(setImageAlign);
            Image _ThumbImage = new Image();
            _htmlTableTd.Controls.Add(_ThumbImage);
            if (Convert.ToString(setBorder) == "True")
            {
                _ThumbImage.BorderStyle = BorderStyle.Solid;
                _ThumbImage.BorderWidth = 1;
            }
            _ThumbImage.ID = ThumbImageName + Count;
            _ThumbImage.ImageUrl = "ImageHandler.ashx?img=" + imageNames[Count - 1] + "&sz=" + Convert.ToString(setThumbImageSize);
            _ThumbImage.Attributes.Add("onclick", "javascript:ImageButton_OnClientClick('" + _mainImage.ClientID + "','" + imageNames[Count - 1] + "','" + setMainImageSize + "');");
        }

        _mainImage.ImageUrl = "ImageHandler.ashx?img=" + imageNames[imageCount - (Count-1)] + "&sz=" + Convert.ToString(setMainImageSize);
    }
Please check out variables in DemoCode, they are simply used as properties.
Once websuercontrol is ready, we simply drag and drop it in Default.aspx page and set following properties of the imageGallery web user control.
protected void Page_Load(object sender, EventArgs e)
    {
        ImageGallary.ImagePath = Server.MapPath("Images");
        ImageGallary.ImageNames = new string[] { "1_1.JPG", "1_2.JPG", "1_3.JPG", "1_4.JPG", "1_5.JPG" };
        ImageGallary.ImageCount = ImageGallary.ImageNames.Length;
        ImageGallary.SetImageAlign = _ImageAlign.Left;
        ImageGallary.SetMainImageSize = _ImageSize.Medium;
        ImageGallary.SetThumbImageSize = _ImageSize.Small;
        ImageGallary.SetBorder = _Border.True;
    } 
Download Democode here---> ImageUserControl.zip Submit this story to DotNetKicks

Read more...