I have written a program that has a feature for viewing images. It works fine for common files types, I simply use a picturebox. But I want to be able to load DNG (Digital Negative) images too.
I don't need to load the whole thing, loading just the baked in jpg preview would be fine, even if not all DNGs have it, I am willing to settle for this to avoid a huge hassle. Plus since DNGs are so big and my program is meant to browse through them quickly this might be best anyway.
I have tried using WindowsAPICodePack.Shell to get the Extra Large Bitmap or Icon from the file. I am already using this for my "explorer" thumbnails. But there is nothing larger than "Large" which I believe is around 256px. I know that the image has something around 1024px jpg preview.
Is there an easy way to get at the jpg preview of a DNG file?
Related
I'm writing a program that uses Win2D to load an image file and display it on the screen. However, the image file itself is about 5 Mb in size, but when I load it using CanvasBitmap.LoadAsync, the process memory jumps up to over 600MB in memory and then settles down to around 300MB. Is there any way to reduce the process memory without having to resize the image manually in an image editor? I've seen code for resizing other types of bitmaps and I was wondering if that's also possible in Win2D.
Regards,
Alex
Update (1/27/2020)
Realized that bitmaps are uncompressed image files, so the only avalible options are either to reduce the image size somehow, or use a different file format. Decided to use the later because I'm working with PDF files. They can be converted into SVG files using Inkscape. Also, SVG files conveniently happen to be supported by Win2D.
I have looked into this fairly extensively, but have not found quite what I am looking for. The two methods I have found are
1: Using the Microsoft.Office.Interop.Excel, Iterate through the workbook's shapes, then copy the images to the clipboard and then take the clipboard data and put that into a bitmap, then finally save that bitmap. The problem with this method is the clipboard. We would like this to be used in a multi-threaded environment and are afraid of clipboard issues between threads. We would rather not deal with clipboard-locking.
2: Save the file as an .HTML file, then grab the images from the "_files" folder created where the document is saved to. The problem with this is that two images get created for each image (1 high res, 1 low res), and there is no good way to determine which images are low-res and which images are high-res, as they are all named image### and some files list them high, low, high, low, while some list them high, high, low, low. Using all of these files is slow and takes up space, which is not ideal. I could check images by aspect ratios, but this is obviously not great because multiple images could have the same aspect ratio.
Is there a way to parse the Excel.Shape directly as a bitmap (or any image format) without using the clipboard? It seems like there must be a way, because the Shape.CopyPicture method is able to send it to the clipboard in an image format.
Otherwise, is there a way to do something similar to number 2 without getting duplicates? I would prefer a solution that avoids using 3rd party libraries.
Thank you.
I assume you use the Excel 2007/2010 format. Every Excel 2007/2010 file is a zip-file! So simply rename your file Excel.xlsx to Excel.zip. Then unzip the file to a folder. The images are in the folder '/xl/media'.
Try this manually. Knowing this, it's easy to automate this by writing a C# program for this.
I have a system for creating a pdf book from users own images. The images are in high resolution and the pdf end up with around 70pages with pictures on most of them.
When generating the pdf the in a local application on the server the process uses around 3Gb of ram which makes it crash more often then it succeeds. The files are also really huge, around 1,2 Gb. Running it through a print to pdf would make it a a hundred times smaller.
Is there a way to make ABCPdf use less memory and creating smaller files?
I have had a very similar experience with iTextSharp, where I was basically running out of memory anytime I create a large PDF with images in it.
I found that there is a function that I should call to release images after I am done with the image, since it holds it in memory in case you want to use it again or until you finally close the PDF.
Either reuse the image if they are repeating header/footer logos, or release images on the go.
Most likely that is the issue you are facing, but I have no experience in ABCPdf.
I've not used ABCPdf directly but I'd suspect that the images are the source of your issues, resize them before they are included in the PDF objects. I suspect that's what a print-to-PDF process will be doing.
One other note, for very large PDF's you may want to set "linearize" to false.
<pdfDoc.SaveOptions.Linearize = false;>
This optimizes the PDF for web streaming, so if you are streaming the PDF, then you might want to leave it as true, but I've found it drastically increases the memory used by ABCPDF during the save.
Goal:
I have lots of pictures in many sizes (both dimensions and file size)
I'd like to convert these files twice:
thumbnail-size pictures
pictures that will look OK on a web page and will be as close to a full screen as possible... and keeping the file size under 500KB.
HTML Questions:
A. What is the best file format to use (jpg, png or other) ?
B. What is the best configuration for web ... as small as possible file size with reasonable quality?
C# Questions
A Is there a good way to achieve this conversion using C# code (if yes, how)?
Try the code in this small C# app for resizing and compressing the graphics. I have reused this code for use in an ASP.NET site without too much work, hopefully you can make use of it. You can run the app to check quality fits your needs etc.
http://blog.bombdefused.com/2010/08/bulk-image-optimizer-in-c-full-source.html
You can pass the image twice, specifying dimensions for a thumbnail, and then again for your display image. It can handle multiple formats (jpg, png, bmp, tiff, gif), and reduce file size significantly without loosing noticeable quality.
On .jpg vs .png, generally jpg is better as you will get a smaller file size than with png. I've generally used this code passing a quality of 90%, which reduces file size significantly, but still looks perfect.
I think PNG is better format for WEB than JPEG that always uses lossy JPG compression, but its degree is selectable, for higher quality and larger files, or lower quality and smaller files. PNG uses ZIP compression which is lossless, and slightly more effective than LZW (slightly smaller files).
In C# you can use System.Drawing namespace types to load, resize and convert mages. This namespace wraps GDI+ API.
A. For graphics I would use png and for fotos jpg.
B. Configuration?
C. There are tons of post that explain that:
http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx
Resizing an Image without losing any quality
I have a winforms image list which contains say like 200 images 256x256.
I use the method Images.FromFile to load the images and then add them to the image list.
According to ANTS .NET profiler, half of the program's time is spent in Images.FromFile. Is there a better way to load an image to add to an image list?
Another thing that might be optimized is, the images that are loaded are larger than 256x256. So is there a way to load them by resizing them first or something? I just want to uniform scale them if they their height is larger than 256 pixels.
Any idea to optimize this?
EDIT: They are JPEGs.
You don't say how much bigger than 256x256 the images actually are - modern digital cameras images are much bigger than this.
Disk I/O can be very slow, and I would suggest you first get a rough idea how many megabytes of data you're actually reading.
Then you can decide if there's a subtle 'Image.FromFile' problem or a simple 'this is how slow my computer/drives/anti-virus scanner/network actually is' problem.
A simple test of the basic file I/O performance would be do to File.ReadAllBytes() for each image instead of Image.FromFile() - that will tell you what proportion of the time was spent with the disk and what with the image handling - I suspect you'll find it's largely disk, at which point your only chance to speed it up might be one of the techniques for getting JFIF thumbnails out of files. Or perhaps one can imagine clever stuff with partial reads of progressive JPEGs, though I don't know if anyone does that, nor if your files are progressive (they're probably not).
I don't really know how fast you need these to load, but if the problem is that an interactive application is hanging while you load the files, then think of ways to make that better for the user - perhaps use a BackgroundWorker to load them asynchronously, perhaps sort the images by ascending file-size and load the small ones first for a better subjective performance.
If you are trying to make thumbnails then try this code here it will let you extract thumbnails without completely loading the image.
You can use FreeImage.NET which is great for loading images on background.
The Image.FromFile contains hidden Mutex which locks your app if you are try to load large images even on background thread.
As for the JPEGs, the FreeImage library uses OpenJPEG library which can load JPEG images in smaller scale more quickly. It can also utilize embedded thumbnails.
The WPF classes also allow loading images in smaller resolution, but this cannot be used if you are restricted to WinForms.
If you want speed then prescale your images, don't do it in runtime.
You didn't mention want type of images you loading (jpeg, png, gif, bmp) of course that bmp is the fastest one since it has not (or almost no) compression.
Are your images 256 colors (8 bit w/ palette), bmp, gif and png support that format that can load pretty fast.
It sounds like you need some sort of image thumbnails? Don't forget that jpeg images already contains thumbnails inside, so you can extract only this small image and you do not need to scale. Such images however smaller than 256x256.
Another option is to move loading logic into separate thread, it will not be faster, but from users perspective it can look as significant speedup.
I have a winforms image list
I would avoid using ImageList in this scenario. Internally, it is an old Windows common control intended for working with GUI icons, usually 32x32 pixels or less.
Another thing that might be optimized is, the images that are loaded are larger than 256x256.
Be aware that GDI+ is not optimized for working with very large bitmaps of the kind that you would normally edit using photo software. Photo editing software packages generally have sophisticated algorithms that divide the image into smaller parts, swap parts to and from disk as needed to efficiently utilize memory, and so on.
Resizing an image is CPU intensive, especially when using a good quality interpolation algorithm. Take a cue from how Windows Explorer does this -- it saves the thumbnails to a file on disk for future access, and it does the processing in the background to avoid monopolizing the system.
This might be too late but using ImageLocation property will do two things
speed up image loading
work around the bug (Image file is locked when you set the PictureBox Image property to a file)
pictureBox1.ImageLocation = "image.jpg";
pictureBox1 .SizeMode = PictureBoxSizeMode.StretchImage;