My company recently had a Hackathon day, where the IT dept. was split into teams and had one day to develop something amazing to present to a panel of judges.
Over the next couple of posts I’d like to just show some things that my team hacked together, as I found them quite interesting, if not amazingly applicable to a real-world app!
First up is a very quick hack I created to generate a composite image on the fly given several other images. Apologies that this is in vb.net and not C#, but I was forced to work within our legacy environment! Assumption: all images to composite are of the same dimensions
Here is a function to take an arraylist of image URLs, merge them, and return the byte array:
Public Function BuildMergedImage(ByVal imgsToMerge As ArrayList) As Byte() 'build image array, loading each image from a stream into the image array Dim imagesToMerge As ArrayList = New ArrayList Dim webClient As System.Net.WebClient = New System.Net.WebClient() Dim imgStream As Stream For Each imgToMerge As String In imgsToMerge imgStream = webClient.OpenRead(imgToMerge.ToString()) imagesToMerge.Add(System.Drawing.Image.FromStream(imgStream)) Next 'get composite dimensions Dim height As Integer = CType(imagesToMerge(0), System.Drawing.Image).Height Dim width As Integer = (CType(imagesToMerge(0), System.Drawing.Image).Width * imagesToMerge.Count()) 'init composite image Dim mergedImage As Bitmap = New Bitmap(width, height) Dim g As Graphics = Graphics.FromImage(mergedImage) 'create composite image For i As Integer = 0 To (imagesToMerge.Count() - 1) g.DrawImage(imagesToMerge(i), (CType(imagesToMerge(i), System.Drawing.Image).Width * i), 0) Next 'save merged image to mem stream Dim imgMemStream As New System.IO.MemoryStream mergedImage.Save(imgMemStream, ImageFormat.Jpeg) 'convert stream to byte array Dim bytes(imgMemStream.Length() - 1) As Byte imgMemStream.Position = 0 imgMemStream.Read(bytes, 0, bytes.Length) imgMemStream.Close() 'return byte array Return bytes End Function
Then to use this method, build up a string arraylist of image urls, pass it to a new function, and output the returned byte array to the response buffer (I used mine in the Page Load, hence the obligatory postback check):
If Not IsPostBack Then Response.Buffer = True Response.ContentType = "image/jpeg" 'match to the imageformat in the composite image function Response.BinaryWrite(BuildMergedImage(taggedImg)) End If
You’ll need these at the top of your file to get it working though. I realise the “option strict off” is a horrid hack, but it was for a hackathon..
Option Strict Off Imports System.IO Imports System.Drawing.Imaging
Bit random, I know, but I found it quite interesting. Have a go with something similar to (but hopefully cleaner than) this:
Dim imageArrayList As ArrayList = new ArrayList For Each imageUrl As String In Request.QueryString("i").Split(CChar("-")) If Not IsNothing(imageUrl) AndAlso Not String.IsNullOrEmpty(imageUrl) Then imageArrayList.Add(imageUrl) End If Next If Not IsPostBack Then Response.Buffer = True Response.ContentType = "image/jpeg" 'match to the imageformat in the composite image function Response.BinaryWrite(BuildMergedImage(imageArrayList)) End If
Example usage (although in this example it’s not pulling the correct dimensions through, which is odd):
http://localhost/combinedimages.aspx?i=http://www.docdatastorage.co.uk/Live/flyfiftythree/ProductImages/savage_white_1_medium.jpg-http://www.docdatastorage.co.uk/Live/flyfiftythree/ProductImages/checkit_green_1_medium.jpg-http://www.docdatastorage.co.uk/Live/flyfiftythree/ProductImages/telemaniacs_navy_1_medium.jpg