We help IT Professionals succeed at work.

I need help... again!

rmmarsh
rmmarsh asked
on
307 Views
Last Modified: 2011-10-03
I have the following code which takes an image from a file and converts it to a thumbnail.  I am in the process of modifying the code to take the image from a table (datatype is nvarchar(max), the new way to do things with MS SQL Server 2005).  I think I finally got the code to insert the image correctly.  Now I want to display it in my Windows program.  Here is the code to get the image from the table:
----------------------------------------------------------------------------
        private void getImage()
        {

            string imageStream = null;
            SqlDataReader rdr = null;

            SqlCommand cmd = new SqlCommand("SELECT ImageType, BookImage FROM tBooks WHERE BookNbr = '" + tbBookNbr.Text + "'",bookConn);
           
            if (bookConn.State == ConnectionState.Closed)
                bookConn.Open();

            rdr = cmd.ExecuteReader();
            while (rdr.Read())
            {
                imageStream = (string)rdr["BookImage"];
            }

            byte[] bytes = System.Text.Encoding.ASCII.GetBytes(imageStream);
            MemoryStream streem = new MemoryStream(bytes);
           
            //System.IO.FileStream stream = new System.IO.FileStream(@"e:\temp\me.jpg", System.IO.FileMode.Open,
            //    System.IO.FileAccess.Read);  <--  this is what was previously passed to the method; I changed it to above 2 lines

            System.IO.MemoryStream tbstream = CreateThumbNail(streem, "jpg", 102, 109);
           
            Bitmap bmp = new Bitmap(tbstream);
            pbBookImage.Image = bmp;
        }
----------------------------------------------------------------------------------------------------------

Here is the supporting code "CreateThumbNail"...
----------------------------------------------------------
        private MemoryStream CreateThumbNail(Stream dataStream, string sFileType, int iHeight, int iWidth)
        {

            EncoderParameters encodeParams = new EncoderParameters();
            long[] quality = new long[1];
            quality[0] = 80;
            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            encodeParams.Param[0] = encoderParam;
            ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();

            ImageCodecInfo jpegICI = null;
            ImageCodecInfo gifICI = null;
            ImageCodecInfo bmpICI = null;
            ImageCodecInfo pngICI = null;

            for (int x = 0; x < arrayICI.Length; x++)
            {
                if (arrayICI[x].FormatDescription.Equals("JPEG"))
                    jpegICI = arrayICI[x];
                else if (arrayICI[x].FormatDescription.Equals("GIF"))
                    gifICI = arrayICI[x];
                else if (arrayICI[x].FormatDescription.Equals("BMP"))
                    bmpICI = arrayICI[x];
                else if (arrayICI[x].FormatDescription.Equals("PNG"))
                    pngICI = arrayICI[x];
            }


            //Get the image from the  stream.
            System.Drawing.Bitmap image = (Bitmap)System.Drawing.Image.FromStream(dataStream);  <-- ERROR IS HERE!


            //Scale factor to resize the image.
            double sImageWidth = image.Width;
            double sImageHeight = image.Height;
            double scaleFactor = 0;

            if (iWidth / sImageWidth < iHeight / sImageHeight)
                scaleFactor = iWidth / sImageWidth;
            else
                scaleFactor = iHeight / sImageHeight;

            int iNewHeight = Convert.ToInt32(sImageHeight * scaleFactor);
            int iNewWidth = Convert.ToInt32(sImageWidth * scaleFactor);


            //Get the thumbnail for the image.
            System.Drawing.Bitmap thumbNail = new System.Drawing.Bitmap(iNewWidth, iNewHeight);
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(thumbNail);
            g.DrawImage(image, new Rectangle(0, 0, thumbNail.Width, thumbNail.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
            image.Dispose();

            MemoryStream ms = new MemoryStream();

            //Save the image corresponding to its Type.
            switch (sFileType)
            {
                case "jpg":
                case "jpeg":
                    thumbNail.Save(ms, jpegICI, encodeParams);
                    break;

                case "bmp":
                    thumbNail.Save(ms, bmpICI, encodeParams);
                    break;

                case "gif":
                    thumbNail.Save(ms, gifICI, encodeParams);
                    break;

                case "png":
                    thumbNail.Save(ms, pngICI, encodeParams);
                    break;

            }
            return ms;

        }
-----------------------------------------------------------------------------------

When running this, I get an error (indicated at ERROR IS HERE) stating the following:  Parameter is not valid.

I don't see the problem... can someone please help me?  AGAIN?  :D

Comment
Watch Question

Top Expert 2004

Commented:
           byte[] bytes = System.Text.Encoding.ASCII.GetBytes(imageStream);
            MemoryStream streem = new MemoryStream(bytes);

why are you converting it to ascii bytes? The error is saying your image is unrecognized ...

Author

Commented:
Hi Greg... what am I supposed to be converting it to?  I know it's stored as bytes on the database and I thought this would be the best way to retrieve it... I need it to be a stream to pass on to the CreateThumbNail method and thought this was the way to do it... you have a better way? (I know you do :D )
Top Expert 2004

Commented:
if its stored as bytes on the server ... read is as bytes ... or if you want to store it as a string base64 encode it Convert.ToBase64String() and Convert.FromBase64String on the other side.

Cheers,

Greg

Author

Commented:
It's stored as nvarchar(max)... is that retrieved as bytes from the server?
Top Expert 2004

Commented:
i dont think so ... I would think that you would use base64 encoding for that data field since its stored as a string.

I am curious why you arent using the "image" or varbinary(max) type?

In the 101 C# 2.0 samples there is a complete example of dealing with images in C# with sql server 2005. http://download.microsoft.com/download/8/1/d/81d789e2-0cbb-421e-b4f9-b40aabadd201/101SamplesCS.msi

Cheers,

Greg

Author

Commented:
According to the lastest SQL Server 2005 online docs, 'image' is going to be replaced in the near future with 'nvarchar(max)' and it says to change one's code to use the new type.  I agree, 'image' would probably have been much easier...

I downloaded the examples, and they pretty much have what I have... the image is apparently not being converted to a stream correctly... I'll keep working on it and get back to you soon...

Thanks again for the help so far...

Rolf

Top Expert 2004

Commented:
its the fact that you are treating it as a string .. and going through encoding .. you are losing data in the conversion.
Top Expert 2004

Commented:
btw: can you show where they say you should use NVARCHAR for binary data unless they are suggesting a base64 encoding with it?

Author

Commented:
Actually, I had stored it incorrectly; fixed it to store as varbinary(max) and got the image stored... still having problems retrieving it, but working on it...

From Books Online:

"ntext, text, and image data types will be removed in a future version of Microsoft SQL Server. Avoid using these data types in new development work, and plan to modify applications that currently use them. Use nvarchar(max), varchar(max), and varbinary(max) instead. For more information, see Using Large-Value Data Types."
Top Expert 2004
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
notice that the satatement lists three type that will be 'deprecated' (ntext, text, and image data types ) and then three type that they should be replaced with (nvarchar(max), varchar(max), and varbinary(max))  this satement means:

ntext ---> nvarchar(max)
text -----> varchar(max)
image ----> varbinary(max)

get the idea?

AW

Author

Commented:
Hi Greg... got it!  This is the statement I used to read the image into a byte array:

                    imageArray = (byte[])data.GetSqlBinary(34);

Thanks again for your help...

Rolf

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.