Is there a good way to read RAW image files (especially Canon CR2 and Adobe DNG files) as GDI+ bitmaps that is reasonably fast?
I found an example running under WPF that would read an image using any installed image codec and then display it in an image control. And I modified this example to create a GDI+ bitmap by writing the WPF image to a MemoryStream and creating the Bitmap from that. But this process is slow! Horribly slow! Opening a simple image takes around 10 seconds on my computer. This solution also requires references to the WPF assemblies and that doesn't feel right, especially not since I would like to run the code in an ASP.NET project.
There are programs that will do batch conversions of the images, but I would prefer converting the images dynamically when requested.
So, any suggestions?
Disclaimer: I work at Atalasoft.
Our DotImage Photo Pro product can do this. If you want to try to do it yourself, look into wrapping the opensource DCRaw or look at how Paint.NET does it (I think there's a RAW plugin for it)
The DotImage Photo Pro component worked well, but I had a problem extracting the preview image from raw files using it. It is also outside my budget for this project.
But, I found the code for a RAW plugin for Paint.NET here and it was quite simple to adapt to my needs. The plugin runs the DCRaw executable usign Process.Start
and reads its output from the StandardOutput
stream. Quite simple and fast! :-)
Edit:
The link to the plugin doesn't work anymore, but here is the code I used to extract the images. The following code extracts the jpg-preview stored in the raw file. If you want the full image you should remove the -e argument. But be aware that for some cameras you will get a ppm-image that GDI+ cannot read.
public Stream GetImageData(string inputFile, string dcRawExe)
{
var startInfo = new ProcessStartInfo(dcRawExe)
{
Arguments = "-c -e \"" + inputFile + "\"",
RedirectStandardOutput = true,
UseShellExecute = false
};
var process = Process.Start(startInfo);
var image = Image.FromStream(process.StandardOutput.BaseStream);
var memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Png);
return memoryStream;
}
Also, you will need a copy of DCRaw. I used the DcrawMS.exe from this site: http://www.insflug.org/raw/Downloads/
Here is a C# port of dcraw, albeit rather old (v8.88) which could be adapted to include newer Canon models:
https://sourceforge.net/projects/dcrawnet/
EDIT :
I just got it to work in my own project for reading EXIF data from RAW files:
- Open project properties and set Output Type to Class Library.
- Recompile.
- Add a reference to the DLL in your own project.
- Add
using dcraw;
at the top. Declare these lines of code:
DcRawState state = new DcRawState(); state.inFilename = filename; state.ifp = new RawStream(filename); Identifier id = new Identifier(state); id.identify(state.ifp);
Now check out all the goodies inside state (assuming your RAW file is supported and didn't cause an exception ;)
来源:https://stackoverflow.com/questions/227604/reading-raw-image-files-as-gdi-bitmaps