tags:

views:

225

answers:

3

I have written some code to create dynamic banners. It returns a bitmap variable. Is there some way that I can use this variable as the ImageUrl for an <asp:Image /> ?

Here is the code that creates the image:

public class SideImage
{
    protected const int ImgCt = 4;
    protected const int ImgW = 130;
    protected const int ImgH = 150;

    public Bitmap GenerateImage()
    {
        string serializedImage = CreateImage("side");

        if(!string.IsNullOrEmpty(serializedImage))
        {
            using(MemoryStream ms = new MemoryStream(Convert.FromBase64String(serializedImage)))
            {
                Bitmap bitmap = new Bitmap(ms);
                return bitmap;
            }
        }
        return null;
    }

    protected string CreateImage(string path)
    {
        try
        {
            using (Bitmap canvas = new Bitmap(ImgW, (ImgCt * ImgH)))
            {
                using (Graphics canvasGraphic = Graphics.FromImage(canvas))
                {
                    List<FileInfo> fileList = new List<FileInfo>();
                    DirectoryInfo directoryInfo = new DirectoryInfo(HttpContext.Current.Server.MapPath(path + "/"));

                    fileList.AddRange(directoryInfo.GetFiles("*.jpg"));

                    Randomizer<FileInfo> randomizer = new Randomizer<FileInfo>();

                    fileList.Sort(randomizer);

                    int yOffset = 0;
                    for (int i = 0; i <= fileList.Count - 1; i++)
                    {
                        using (Image image = Image.FromFile(fileList[i].FullName))
                        {
                            Rectangle rectangle = new Rectangle(0, yOffset, ImgW, ImgH);
                            canvasGraphic.DrawImage(image, rectangle);
                        }
                        yOffset += ImgH;
                    }

                    ImageCodecInfo[] imageCodecInfo = ImageCodecInfo.GetImageEncoders();
                    using (EncoderParameters encoderParameters = new EncoderParameters(2))
                    {

                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, 100L);
                            encoderParameters.Param[1] = new EncoderParameter(Encoder.ColorDepth, 16L);

                            canvas.Save(memoryStream, imageCodecInfo[1], encoderParameters);
                            return Convert.ToBase64String(memoryStream.GetBuffer());
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}

public class Randomizer<T> : IComparer<T>
{
    protected Random Salter;
    protected int Salt;
    protected SHA1 Sha1;

    public Randomizer()
    {
        Salter = new Random();
        Salt = Salter.Next();
        Sha1 = new SHA1Managed();
    }
    public Randomizer(int seed)
    {
        Salter = new Random(seed);
        Salt = Salter.Next();
        Sha1 = new SHA1Managed();
    }
    private int HashAndSalt(int value)
    {
        byte[] b = Sha1.ComputeHash(BitConverter.GetBytes(value));
        int r = 0;
        for (int i = 0; i < (b.Length - 1); i += 4)
        {
            r = r ^ BitConverter.ToInt32(b, i);
        }
        return r ^ Salt;
    }

    public int Compare(T x, T y)
    {
        return HashAndSalt(x.GetHashCode().CompareTo(HashAndSalt(y.GetHashCode())));
    }
}
+1  A: 

This sounds similar to how chart generators work. There are two approaches to this that I've seen. One is to create a file on the server and then point to that. The other is to store the bitmap in memory and then call an aspx page in place of the image. The ASP page would read the bitmap from memory and return to the browser.

Jon B
OK I think that is what I did before, originally in VB.NET. Thanks!
Anders
+3  A: 

See the content of this question for couple of different approaches to this sort thing.

(Obviously I prefer mine ;) ).

AnthonyWJones
A: 

I'd create an HTTP module to do this.

You could setup the HTTP module to intercept all requests to a particular folder ('/images/generated/') for example.

Then, when you get a request for an image in this folder, the code in your HTTP module will be called. Create your image in memory and write it out to the Response object (having set any appropriate MIME type headers and things first).

In your HTML you can then write an image tag like <img src="/images/generated/image-doesnt-physically-exist.jpg" /> and still get an image back.

Hope that helps point you in the right direction!

Chris Roberts
An HttpHandler would be the better option in this case, not an HttpModule.
Jeff Hardy