Link to home
Start Free TrialLog in
Avatar of ashblack
ashblack

asked on

VB.Net (Visual Basic) How to generate a bitmap, pixel by pixel, then save to .jpg?

Hi there,

I'm writing a simple app that reads an ordered recordset from SQL then visualizes each cell as a unique pixel with shading between 0 and 255 in the alpha layer.  (Basically, I'm creating a raster image as you would find in a GIS).  My app works great for drawing the image to screen (bitmap), but when it saves to .jpg the resulting file contains only 2 colors - dark blue for the "-99.9999" value, and solid red for the <> "-99.9999" values.  I think the problem is related to a step missing between the setting of individual pixels and the "Save to File" command, but I don't really know.  Here's the code:

            '-----------------------------
            'DECLARE Variables
            '-----------------------------
            pictureBox1.Size = New Size(595, 506)
            Me.Controls.Add(pictureBox1)
            Dim flag As New Bitmap(595, 506)

            'Declare .jpg file
            Dim ThisOutput As New Bitmap(596, 507)
            Dim file_name As String = Application.ExecutablePath
            file_name = "filename"

            Dim flagGraphics As Graphics = Graphics.FromImage(flag)
            Dim jpgGraphics As Graphics = Graphics.FromImage(ThisOutput)

            Dim ThisVal As Double = 0.0
            Dim ThisPixVal As Double = 0.0
            Dim Northing As Integer = 0
            Dim Easting As Integer = 0
            
            'READ image data from SQL
            Dim Conn As SqlConnection = OpenConnection()
            Dim Com As SqlCommand = New SqlCommand("SQL_Statement", Conn)
            Dim reader As SqlDataReader = Com.ExecuteReader()

            'Loop thru Image data
            Northing = 0
            Easting = 0
            While reader.Read()

                  ThisVal = reader(0)

                  'Draw the pixel value
                  If ThisVal <> -99.9999 Then

                        ThisPixVal = Math.Round((ThisVal + 8.9475) * 8.3256)' a constant
                        Dim shadowBrush As New SolidBrush(Color.FromArgb(ThisPixVal, Color.Red))
                        flagGraphics.FillRectangle(shadowBrush, Easting, Northing, 1, 1)
                        ThisOutput.SetPixel(Easting, Northing, Color.FromArgb(ThisPixVal, Color.Red))

                  Else

                        flagGraphics.FillRectangle(Brushes.DarkBlue, Easting, Northing, 1, 1)
                        ThisOutput.SetPixel(Easting, Northing, Color.DarkBlue)

                  End If

                  'Increment Easting, Northing
                  Easting = Easting + 1
                  If Easting = 595 Then
                        Easting = 0
                        Northing = Northing + 1
                  End If

            End While

            'Close the reader
            reader.Close()

            'Save to file
            ThisOutput.Save(file_name & ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

            'Draw bitmap to screen
            pictureBox1.Image = flag

Looking forward to some help!

--ash
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

So "flag" is correct but "ThisOuput" is not?  Are they supposed to be exactly the same?

If so, why not try saving flag instead?  (and ditching ThisOutput)
 
    flagGraphics.Dispose()
    flag.Save(file_name & ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
Avatar of ashblack
ashblack

ASKER

Idle_Mind,

No, that's not correct.

'flag' is a bitmap that is drawn to screen (successfully, blue, and 256 shades of Red).

'ThisOutput' is a bitmap that is saved to file as .jpg. When saved to disc, it creates a file with only two colors in it (blue, red).

--ash
Or rather, yes, they are supposed to be exactly the same, but one is headed for the screen the other is head for file.

Saving 'flag' to .jpg has the same (2 color) result as saving 'ThisOutput' to .jpg

--ash
Idle_mind, hello again,

Just to be clear, I did try ditching 'ThisOutput' as you suggested:

  flagGraphics.Dispose()
    flag.Save(file_name & ".jpg", System.Drawing.Imaging.ImageFormat.Jpeg)

and I'm still getting the "2 colors only" result.

Thanks for checking into this...

--ash


But it displays correctly on the screen?  Can you post a screen shot?
Sure,

Here's the result of 'flag' which is a bitmap being drawn to screen...
AW-1.jpg
... and here's the output of 'ThisOutput' which is being written to .jpg.
256ColorTest.jpg
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ahhh, it works as a .png!

I might be able to proceed with a .png format (I'll check into it tomorrow), but this insight seems to imply that the problem is related to how .jpg, .bmp and .gif are handled by:

System.Drawing.Imaging.ImageFormat
 
you think?

It would be nice to get to the bottom of this problem...

Thanks for the suggestion, feeling better about resolving this now.

--ash



The problem wasn't resolved, only worked around.  But I appreciate IdleMind's input nonetheless, so here's your points!