473,698 Members | 2,426 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Add an EXIF/JPG thumbnail to a jpg

tlhintoq
3,525 Recognized Expert Specialist
I'd like to think I can work out most issues, but this one is kicking my butt.
What's worse, is that I know I can't be the first guy to want to add a thumbnail to jpg that doesn't already have one. I see it in plenty of other applications. Yet I can't seem to make it work despite being so very close.

I know the problem has to be in how I am making the PropertyItem of the thumbnail - because if I comment out lines 24-34 the JPG saves fine, just without a built-in thumbnail.

So I'm either wrong between lines 8-14 where I convert the bitmap NewThumbnail into a byte array, or I'm wrong in how I'm making the thumbnail property.

But for the life of me I can't seem to work it out.

Any assistance in this would be greatly appreciated.

Expand|Select|Wrap|Line Numbers
  1.         public static void WriteNewThumbnailInImage(string Filename, Bitmap NewThumbnail)
  2.         {
  3.             Bitmap Pic;
  4.             PropertyItem[] PropertyItems;
  5.             string FilenameTemp;
  6.  
  7.  
  8.             #region Turn bitmap into an array of bytes
  9.             MemoryStream thumbstream = new MemoryStream();
  10.             NewThumbnail.Save(thumbstream, ImageFormat.Jpeg);
  11.             byte[] Thumb = thumbstream.ToArray();
  12.             //// copy thumbnail into byte array
  13.             //for (i = 0; i < Thumb.Length; i++) Thumb[i] = (byte)Thumb[i];
  14.             #endregion Turn bitmap into an array of bytes
  15.  
  16.  
  17.             #region Read JPG from HDD - it was saved with no EXIF
  18.             Image TempImage = Image.FromFile(Filename);
  19.             Pic = (Bitmap)TempImage.Clone();
  20.             TempImage.Dispose();
  21.             #endregion Read JPG from HDD - it was saved with no EXIF
  22.  
  23.  
  24.             #region If comment this out then the final image saves fine, but with no built-in thumbnail
  25.             //put the new Thumbnail into the right property item
  26.             PropertyItems = Pic.PropertyItems;
  27.             //PropertyItems[0].Id = 0x010e; // 0x010e as specified in EXIF standard for DESCRIPTION
  28.             PropertyItems[0].Id = 20507;// Every example uses this as the READ location for EXIF thumbnail.
  29.             //PropertyItems[0].Type = 1; // 1 = Array of bytes
  30.             PropertyItems[0].Type = 6; // 6 = Array of bytes that can hold any data type
  31.             PropertyItems[0].Len = Thumb.Length;
  32.             PropertyItems[0].Value = Thumb;
  33.             Pic.SetPropertyItem(PropertyItems[0]);
  34.             #endregion If comment this out then the final image saves fine, but with no built-in thumbnail
  35.  
  36.  
  37.             // we cannot store in the same image, so use a temporary image instead
  38.             FilenameTemp = Filename + ".temp";
  39.             try
  40.             {
  41.                 using (EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)70))
  42.                 {// Encoder parameter for image quality
  43.  
  44.  
  45.                     // Jpeg image codec
  46.                     ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg");
  47.  
  48.                     if (jpegCodec == null)
  49.                         return;
  50.                     EncoderParameters encoderParams = new EncoderParameters(1);
  51.                     encoderParams.Param[0] = qualityParam;
  52.  
  53.                     Pic.Save(FilenameTemp, jpegCodec, encoderParams);
  54.  
  55.                 }
  56.  
  57.             }
  58.             catch (Exception emg)
  59.             {
  60.                 Console.WriteLine("EXIF #####################################################");
  61.                 Console.WriteLine(emg.Message);
  62.                 Console.WriteLine(emg.StackTrace);
  63.             }
  64.  
  65.  
  66.             return;
  67. }

Of course error messages that don't tell you much don't help either.
Yippee, a generic error - let me track that right down.
Expand|Select|Wrap|Line Numbers
  1. A generic error occurred in GDI+.
  2.    at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
  3.    at WriteNewThumbnailInImage(String Filename, Bitmap NewThumbnail)
  4. [...]
  5. A first chance exception of type 'System.Runtime.InteropServices.ExternalException' occurred in System.Drawing.dll
  6. The thread 0x15dc has exited with code 0 (0x0).
Oct 28 '09
15 13282
tlhintoq
3,525 Recognized Expert Specialist
I finally found an explanatin of property ID and propety type to use for. The EXIF 2.2 specification PDF. Imagine that. But geez these guys went out of the way to make that document hard to understand and still lacks a great deal of practical info.

ThumbnailCompre ssion according to the spec is merely set to 1 if not and 6 if jpg compression. No other description about it.

Right now I've gotten this to read and write JPEG thumbnail into EXIF data of a JPEG image. Hurray! The only part I am hesitant about is that it isn't in the property that I have always seen used for thumbnails: 20507. What is working is working in property 34675. The exact same code that works into 34675 does not work if I change the ID to 20507 and re-run it. Totally weird. By the way, no other property had to be set to anything. 34675 will accept the byte[] from Image.save(memo rystream). Which makes sense as the saved memory stream contains all the info needed to read and translate a compressed JPG.
Oct 30 '09 #11
Plater
7,872 Recognized Expert Expert
Wierd, 34675 I have listed as PropertyTagICCP rofile
Nov 2 '09 #12
tlhintoq
3,525 Recognized Expert Specialist
yah... Exactly what I'm saying. It's weird, but it works. Right now this is intended for an in-house proprietary set of applications. So as long as application 'a' can find the thumb where application 'b' puts it, then all is good. But in the long run I would like to do it *right* and have things compatible with all other applications that actually follow industry standards.
Nov 2 '09 #13
tlhintoq
3,525 Recognized Expert Specialist
Ok. Finally got this working. Little tidbit that is hard to find: The maximum size allowed is 160x160 and must be in the same aspect ratio as the full size image.

Expand|Select|Wrap|Line Numbers
  1. #region Create a new standard thumbnail property.
  2. //Max of 160x160 in same aspect ratio as main image
  3. Image SmallThumb = tlhintoq.GDI.Graphics.CalculatedThumbnail(NewThumbnail, 160, 160);
  4. MemoryStream MS = new MemoryStream();
  5. SmallThumb.Save(MS, ImageFormat.Jpeg);
  6. SmallThumb.Dispose();
  7. MS.Position = 0;
  8. byte[] smallthumbbytes = MS.ToArray();
  9.  
  10. PropertyItems = Pic.PropertyItems;
  11. PropertyItems[0].Id = 0x501b; // PropertyTage ThumbnailData
  12. PropertyItems[0].Type = 1;
  13. PropertyItems[0].Len = smallthumbbytes.Length;
  14. PropertyItems[0].Value = smallthumbbytes;
  15. Pic.SetPropertyItem(PropertyItems[0]);
  16.  
  17. #region Create a new Thumbnail Compression property.
  18. PropertyItems = Pic.PropertyItems;
  19. PropertyItems[0].Id = 0x5023; // PropertyTagThumbnailCompression
  20. PropertyItems[0].Type = (short)ImagePropertyTagValueTypes.ArrayOfUnisignedShort3;
  21. PropertyItems[0].Len = 2;
  22. PropertyItems[0].Value = new byte[] { 6, 0 };
  23. Pic.SetPropertyItem(PropertyItems[0]);
  24. #endregion
Nov 2 '09 #14
Plater
7,872 Recognized Expert Expert
So now your thumbnails will be read by windows in the file explorer yes?
Nov 2 '09 #15
tlhintoq
3,525 Recognized Expert Specialist
They seem to be. SInce Windows7 tries to build new thumbs even if there is no EXIF included, then stick them in the thumbsdb I can only go by the speed. But it seems to be working.

I guess I should dig up a program that is known to load the industry standard thumb and display it.
Nov 2 '09 #16

Sign in to post your reply or Sign up for a free account.

Similar topics

1
3650
by: Phil Powell | last post by:
PHP 4.3.2 with --enable-exif I have the following class: <?php class ThumbGenerator extends MethodGeneratorForActionPerformer { function ThumbGenerator() { // CONSTRUCTOR
4
9407
by: Jan Schmidt | last post by:
Hi NG, i created my own Picture Gallery, which reads the EXIF Data of each Picture before displaying on website. I'd like to give my users the ability to alter some opened EXIF Values. It would reduce the Traffic, because users don't need to upload the whole Picture because of an missing, or bad Value of EXIF Data. But i still can't find a solution to write EXIF Data via php... I mean reading with php is no problem, but for writing...
0
1899
by: leo | last post by:
hi there i'm using gene cash's EXIF.py module to find out the shoting time of an jpeg image. this module works usually like a beauty, but some images raise an exception: Traceback (most recent call last): File "/Users/Shared/bin/exiftool.py", line 148, in ? tags=EXIF.process_file(f)
4
14204
by: thomas kern | last post by:
Hello, i dont know how to extract the thumbnail of an image? is there a good way to do that cos there arent many articles on the internet :/ thank you thomas
1
4955
by: Alfonso Acosta | last post by:
Hi all, exif_read_data() doesn't support URLs (http://php.net/manual/en/function.exif-read-data.php ) but I would like to do that with the minimum traffic and overhead possible. A naive solution would be downloading the whole target file locally and then call exif_read_data() but that means a lot of overhead traffic
14
5229
by: Frank | last post by:
I see that ImageFormat includes exif. But I can't find out if I've System.Drawing.Image.FromStream or something like it can read and/or write that format.
2
8160
by: Milagro | last post by:
Hi, I'm using the code below to create thumbnails from photos. The code works fine and thumbnails are created. However, thumbnails of vertical photos are oriented as horizontal photos. More info: These photos come from a Nikon high end SLR digital camera. It's not my camera so I have no control over how the image is taken. If I open a vertical image in Photoshop (CS2), the image is oriented
2
2914
by: iKER- | last post by:
Hi! I´m working in a program witch need to read Exif data from my Sony Alpha A100 raw (arw extension) pictures. I found a table with keys for read it, but i can´t read. I tried something, but i can´t. I found this "table": Full table is there: http://owl.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html **************** Tag ID Tag Name Writable Group Values / Notes
1
2773
by: SPE - Stani's Python Editor | last post by:
Phatch is a simple to use cross-platform GUI Photo Batch Processor Phatch handles all popular image formats and can duplicate (sub)folder hierarchies. It can batch resize, rotate, apply perspective, shadows, rounded corners, ... and more in minutes instead of hours or days if you do it manually. Phatch allows you to use EXIF and IPTC tags for renaming and data stamping. Phatch also supports a console version to batch photos on web...
0
8609
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9166
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9030
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8899
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7737
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6525
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5861
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
2333
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.