Link to home
Start Free TrialLog in
Avatar of rmmarsh
rmmarshFlag for United States of America

asked on

I need help... again!

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

Avatar of gregoryyoung
gregoryyoung
Flag of Canada image

           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 ...
Avatar of rmmarsh

ASKER

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 )
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
Avatar of rmmarsh

ASKER

It's stored as nvarchar(max)... is that retrieved as bytes from the server?
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

Avatar of rmmarsh

ASKER

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

its the fact that you are treating it as a string .. and going through encoding .. you are losing data in the conversion.
btw: can you show where they say you should use NVARCHAR for binary data unless they are suggesting a base64 encoding with it?
Avatar of rmmarsh

ASKER

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."
ASKER CERTIFIED SOLUTION
Avatar of gregoryyoung
gregoryyoung
Flag of Canada 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
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
Avatar of rmmarsh

ASKER

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