1

I can create an image on the server from a byte array stored in the database. But how do I combine each byte array into one image. Basically I want to stack them on top of each other (they are all 1366px width and 618px height) and then save that to a png image. I will then get that image from the server and return to the web page (which I can do now for one image). Hope you can help.

This code in asp.net web forms creates an image which i return the filename as a return in a webmethod function back to the browser.

 Public Shared Function Base64ToImage(ByVal base64String As String, ByVal id As String) As String
        'http://www.dailycoding.com/Posts/convert_image_to_base64_string_and_base64_string_to_image.aspx
        ' Convert Base64 String to byte[]

        Dim sFileName As String = String.Empty

        Try
            Dim imageBytes As Byte() = Convert.FromBase64String(base64String)
            Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)

            ' Convert byte[] to Image
            ms.Write(imageBytes, 0, imageBytes.Length)
            Dim image__1 As Image = Image.FromStream(ms, True)

            sFileName = "img_" & id & ".png"

            Dim sPath As String = HttpContext.Current.Server.MapPath("images\")

            image__1.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)
        Catch ex As Exception

        End Try

        '
        Return sFileName
    End Function

I have tried this, looping through the records and then trying to combine them with sourcecopy but I can't get it to combine them?

Public Shared Function Base64ToImage2(ByVal dt As DataTable) As String

        ' Convert Base64 String to byte[]

        Dim sFileName As String = String.Empty
        Dim base64String As String, id As String

        'if first record create image 
        'on 2nd or greater in dt then combine images
        Try

            Dim iCount As Integer = 0
            Dim image__1 As Image = Nothing
            Dim compositeImage As Image = Nothing
            Dim sPath As String = String.Empty

            If dt.Rows.Count > 0 Then
                For Each myRow As DataRow In dt.Rows
                    'getImage = getImage() & Base64ToImage(myRow("image_data").ToString(), myRow("id").ToString()) & "|"

                    If iCount = 0 Then

                        Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
                        Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)

                        ' Convert byte[] to Image
                        ms.Write(imageBytes, 0, imageBytes.Length)
                        image__1 = System.Drawing.Image.FromStream(ms)

                        'sFileName = "img_1.png"
                        'sPath = HttpContext.Current.Server.MapPath("images\")
                        'image__1.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)

                        'compositeImage = New Bitmap(image__1.Width, image__1.Height)

                    Else

                        Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
                        Dim ms2 As New MemoryStream(imageBytes, 0, imageBytes.Length)

                        ' Convert byte[] to Image
                        ms2.Write(imageBytes, 0, imageBytes.Length)
                        Dim image__2 As Image = System.Drawing.Image.FromStream(ms2)

                        Dim g As Graphics = Graphics.FromImage(image__1)
                        g.CompositingMode = CompositingMode.SourceCopy

                        g.DrawImage(image__2, 0, image__1.Height)

                        sFileName = "img_1.png"
                        'sPath = HttpContext.Current.Server.MapPath("images\")
                        'image__2.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)

                    End If
                    iCount = iCount + 1
                Next myRow
            End If

            'sFileName = "img_1.png"
            'Dim sPath As String = HttpContext.Current.Server.MapPath("images\")
            'compositeImage.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)

        Catch ex As Exception

        End Try

        '
        Return sFileName
    End Function
Rob
  • 1,226
  • 3
  • 23
  • 41
  • 1
    is this what you are looking for http://stackoverflow.com/questions/465172/merging-two-images-in-c-net – Shoaib Shaikh Jan 06 '12 at 05:46
  • @Shoaib I have png's as byte64 strings in the database that I convert into a memory stream (as shown above in Base64ToImage(). I would like to cobmine the memory stream 'images' into one (overlaying each on top of each other) instead of using physical images. – Rob Jan 06 '12 at 14:50

2 Answers2

1

Solved! After a ton of searching and reading I was able to combine png images into one! Each image is created from a memory stream and then appended to a bitmap with NewRectangle which is the key. Once I loop through the records from the database, I have one image which is downloaded to the client in a webmethod return. The width and height are pulled from the client to the webmethod and passed into the function so the image is scaled to fit the browser inner dimensions (to avoid any scrollbars).

JS on the client for the dimensions: mywidth = window.innerWidth myheight = window.innerHeight

The code to convert the base64 byte image is as follows...

Public Shared Function Base64ToImage2(ByVal dt As DataTable, ByVal Image_Width As String, ByVal Image_Height As String) As String

        Dim sFileName As String = String.Empty
        Dim sPath As String = HttpContext.Current.Server.MapPath("images\")
        Dim myimage As Image = Nothing

        ' Create a new bitmap object 400 pixels wide by 60 pixels high
        Dim objBitmap As New Bitmap(CInt(Image_Width), CInt(Image_Height))

        '' Create a graphics object from the bitmap
        Dim objGraphic As Graphics = Graphics.FromImage(objBitmap)

        'if first record create image
        'on 2nd or greater in dt then combine images
        Try    

            If dt.Rows.Count > 0 Then
                For Each myRow As DataRow In dt.Rows


                    Dim imageBytes As Byte() = Convert.FromBase64String(myRow("image_data").ToString())
                    Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)

                    ' Convert byte[] to Image
                    ms.Write(imageBytes, 0, imageBytes.Length)
                    myimage = System.Drawing.Image.FromStream(ms)

                    objGraphic.DrawImage(myimage, New Rectangle(0, 0, CInt(Image_Width), CInt(Image_Height)))

                Next myRow

                sFileName = "img_1.png"
                objBitmap.Save(sPath & sFileName, System.Drawing.Imaging.ImageFormat.Png)

            End If



        Catch ex As Exception

        End Try

        '
        Return sFileName
    End Function
Rob
  • 1,226
  • 3
  • 23
  • 41
0

In case someone else is looking for something similar in C# where you're trying to load an image source with the result, here's the code:

        private void LoadImage()
        {
            string src = string.empty;
            byte[] mergedImageData = new byte[0];

            mergedImageData = MergeTwoImageByteArrays(watermarkByteArray, backgroundImageByteArray);
            src = "data:image/png;base64," + Convert.ToBase64String(mergedImageData);
            MyImage.ImageUrl = src;
        }

        private byte[] MergeTwoImageByteArrays(byte[] imageBytes, byte[] imageBaseBytes)
        {
            byte[] mergedImageData = new byte[0];
            using (var msBase = new MemoryStream(imageBaseBytes))
            {
                System.Drawing.Image imgBase = System.Drawing.Image.FromStream(msBase);
                Graphics gBase = Graphics.FromImage(imgBase);
                using (var msInfo = new MemoryStream(imageBytes))
                {
                    System.Drawing.Image imgInfo = System.Drawing.Image.FromStream(msInfo);
                    Graphics gInfo = Graphics.FromImage(imgInfo);
                    gBase.DrawImage(imgInfo, new Point(0, 0));
                    //imgBase.Save(Server.MapPath("_____testImg.png"), ImageFormat.Png);
                    MemoryStream mergedImageStream = new MemoryStream();
                    imgBase.Save(mergedImageStream, ImageFormat.Png);
                    mergedImageData = mergedImageStream.ToArray();
                    mergedImageStream.Close();
                }
            }
            return mergedImageData;
        }
Lukas
  • 2,885
  • 2
  • 29
  • 31