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
Solved

Create a Thumbnail from image after upload

Posted on 2014-12-12
11
110 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
  • 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
Webinar: Aligning, Automating, Winning

Join Dan Russo, Senior Manager of Operations Intelligence, for an in-depth discussion on how Dealertrack, leading provider of integrated digital solutions for the automotive industry, transformed their DevOps processes to increase collaboration and move with greater velocity.

 
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

Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

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…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

792 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