[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 126
  • Last Modified:

Create a Thumbnail from image after upload

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
RecipeDan
Asked:
RecipeDan
  • 7
  • 3
1 Solution
 
LordWabbitCommented:
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
 
LordWabbitCommented:
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
 
käµfm³d 👽Commented:
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
RecipeDanAuthor Commented:
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
 
LordWabbitCommented:
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
 
RecipeDanAuthor Commented:
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
 
RecipeDanAuthor Commented:
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
 
RecipeDanAuthor Commented:
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
 
RecipeDanAuthor Commented:
I wanted to add. The original image that was upload is fine. I can display it.
0
 
RecipeDanAuthor Commented:
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
 
RecipeDanAuthor Commented:
I figured it out and it is the best solution.
0

Featured Post

Free recovery tool for Microsoft Active Directory

Veeam Explorer for Microsoft Active Directory provides fast and reliable object-level recovery for Active Directory from a single-pass, agentless backup or storage snapshot — without the need to restore an entire virtual machine or use third-party tools.

  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now