Solved

Create a Thumbnail from image after upload

Posted on 2014-12-12
11
118 Views
Last Modified: 2014-12-20
Hello:

I am trying to create a thumbnail from an image after it is uploaded. I am getting an error: An exception of type 'System.IO.FileNotFoundException' occurred in System.Drawing.dll but was not handled in user code.

           HttpFileCollection hfc = Request.Files;
            for (int i = 0; i < hfc.Count; i++)
            {
                HttpPostedFile hpf = hfc[i];
                string strFilename = Path.GetFileName(hpf.FileName);
                Image image = Image.FromFile(strFilename);
                Image thumb = image.GetThumbnailImage(100, 100, () => false, IntPtr.Zero);
                string strFilenameThumb = Path.ChangeExtension(strFilename, "thumb");
	    }

Open in new window

0
Comment
Question by:RecipeDan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
11 Comments
 
LVL 11

Expert Comment

by:LordWabbit
ID: 40496868
Image image = Image.FromFile(strFilename);

Open in new window

loads an image from disk, since this is server side code it is trying to load a file from the full path of strFileName
however
string strFilename = Path.GetFileName(hpf.FileName);

Open in new window

is only extracting the file name of the file instead of the full file path.  Not sure where your files are being stored and the attempt to access them is, but clearly they are not the same default locations.  I would suggest setting breakpoints on both and seeing if they FULL absolute paths match, this will probably tell you why using the relative paths is giving you a file not found error and you can adjust the relative paths respectively so that they DO match.
0
 
LVL 11

Expert Comment

by:LordWabbit
ID: 40496946
Just noticed something, the Request.Files are the files in the request collection in MIME format, they are not written to disk yet.  The Image.FromFile is reading from disk, it expects there to be a physical file.  You either need to write the files to disk first (terrible idea) or create the image from a stream.
            // create an array of the appropriate size to house the stream
            byte[] byteMe = new byte[Request.Files[0].InputStream.Length];
            // load the stream of butes into the array
            Request.Files[0].InputStream.Read(byteMe, 0, (int)Request.Files[0].InputStream.Length);
            // create a memory stream and using that create an image
            System.Drawing.Image img = System.Drawing.Image.FromStream(new System.IO.MemoryStream(byteMe));
            // back to your code to create a thumbnail
            System.Drawing.Image thumb = img.GetThumbnailImage(100, 100, () => false, IntPtr.Zero);

Open in new window

Not sure what you want to do with the thumbnail afterwards?  
The reason I mention writing to disk being a terrible idea only applies if you actually don't want to keep the full image.  Writing to disk to 'bridge' the gap between two seperate functions is bad, then you have to write garbage collection routines etc. etc. or in a few days/weeks/months you run out of disk space due to unwanted images.
Also notice that for Image I had to use the fully qualified name as at this point there is a class name conflict between namespaces.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40497112
0
Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

 
LVL 1

Author Comment

by:RecipeDan
ID: 40497582
My apologies, I just saw that I didn't copy and paste all of my code. I am uploading my files to a Blob on Azure. The code below works for the upload. I tested both of your codes and they work. How would I get the filename of the new thumbnail image and upload to the blob?

            HttpFileCollection hfc = Request.Files;
            for (int i = 0; i < hfc.Count; i++)
            {
                HttpPostedFile hpf = hfc[i];
                string trainingfolder = "Dan"
                string strFilename = Path.GetFileName(hpf.FileName);

                CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
                CloudBlobContainer container = blobClient.GetContainerReference(trainingfolder);
                CloudBlockBlob blockBlob = container.GetBlockBlobReference(strFilename);
                blockBlob.Properties.ContentType = hpf.ContentType;
                blockBlob.UploadFromStream(hpf.InputStream);
            
            }

Open in new window

0
 
LVL 11

Expert Comment

by:LordWabbit
ID: 40497664
hpf.FileName is the filename, so if I uploaded an image C:\Images\LordWabbit.jpg the value in hpf.FileName would be LordWabbit.jpg.  Doing a Path.GetFileName(hpf.FileName) on that would do nothing and return LordWabbit.jpg.
0
 
LVL 1

Author Comment

by:RecipeDan
ID: 40498074
Correct. I understand that part of it. What I do not know is how to upload an image to a blob created on a server. The example I gave above uploads the file from a direct path. The same script does not work with files like the thumbnails that are created on a server.
0
 
LVL 1

Author Comment

by:RecipeDan
ID: 40498956
I wrote this code below. It uploads a file to the blob. However, the file has 0 bytes.

                string trainingfolder = "Dan"
                string strFilename = Path.GetFileName(hpf.FileName);
                string strFile = Path.GetFileNameWithoutExtension(hpf.FileName);
                string strFileExt =  Path.GetExtension(hpf.FileName);
                System.Drawing.Image image = System.Drawing.Image.FromStream(hpf.InputStream);
                System.Drawing.Image thumbnailImage = image.GetThumbnailImage(100, 100, null, IntPtr.Zero);
                MemoryStream imageStream = new MemoryStream();
                thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                string NewImageName = strFile + "_thumb" + strFileExt;  
                if (imageStream.Length > 0)
                {
                    CloudStorageAccount storageAccount1 = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                    CloudBlobClient blobClient1 = storageAccount1.CreateCloudBlobClient();
                    CloudBlobContainer container1 = blobClient1.GetContainerReference(trainingfolder);
                    CloudBlockBlob blockBlob1 = container1.GetBlockBlobReference(NewImageName);
                    blockBlob1.UploadFromStream(imageStream);
                }

Open in new window

0
 
LVL 1

Author Comment

by:RecipeDan
ID: 40499305
OK after working with the code further. I got it to create an image image that has data. However, it does not display. When I download it, I get an error saying invalid Bitmap.

                byte[] originalImage;
                string imageUrl = "https://abc123.com/12.jpg";
                originalImage = new System.Net.WebClient().DownloadData(imageUrl);
                System.IO.MemoryStream imageStream = new System.IO.MemoryStream(originalImage);
                System.Drawing.Image img = System.Drawing.Image.FromStream(imageStream);
                System.Drawing.Image thumbnailImage = img.GetThumbnailImage(100, 100, () => false, IntPtr.Zero);
                thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                string NewImageName = strFile + "_thumb" + strFileExt;
                if (imageStream.Length > 0)
                {
                    CloudStorageAccount storageAccount2 = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                    CloudBlobClient blobClient2 = storageAccount2.CreateCloudBlobClient();
                    CloudBlobContainer container2 = blobClient2.GetContainerReference(trainingfolder);
                    CloudBlockBlob blockBlob2 = container2.GetBlockBlobReference(NewImageName);

                    blockBlob2.Properties.ContentType = "image/jpeg";
                    blockBlob2.UploadFromStream(imageStream);
                }

Open in new window

0
 
LVL 1

Author Comment

by:RecipeDan
ID: 40499310
I wanted to add. The original image that was upload is fine. I can display it.
0
 
LVL 1

Accepted Solution

by:
RecipeDan earned 0 total points
ID: 40499715
OK. I figured it out. Just add imageStream.Position = 0; before upload.                

              string trainingfolder = "Dan"
                string strFilename = Path.GetFileName(hpf.FileName);
                string strFile = Path.GetFileNameWithoutExtension(hpf.FileName);
                string strFileExt =  Path.GetExtension(hpf.FileName);
                System.Drawing.Image image = System.Drawing.Image.FromStream(hpf.InputStream);
                System.Drawing.Image thumbnailImage = image.GetThumbnailImage(100, 100, null, IntPtr.Zero);
                MemoryStream imageStream = new MemoryStream();
                thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                string NewImageName = strFile + "_thumb" + strFileExt;  
                if (imageStream.Length > 0)
                {
                    CloudStorageAccount storageAccount1 = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
                    CloudBlobClient blobClient1 = storageAccount1.CreateCloudBlobClient();
                    CloudBlobContainer container1 = blobClient1.GetContainerReference(trainingfolder);
                    CloudBlockBlob blockBlob1 = container1.GetBlockBlobReference(NewImageName);
imageStream.Position = 0;                 
   blockBlob1.UploadFromStream(imageStream);
                }

Open in new window

0
 
LVL 1

Author Closing Comment

by:RecipeDan
ID: 40510571
I figured it out and it is the best solution.
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question