Reading raw image files in c# - c#

How do i decode/open raw image files like .CR2 or .NEF and .ARW without having the codec installed, something like lightroom open raw files ? My code look like this:
if (fe == "CR2" | fe == "NEF" | fe == "ARW" )
{
BitmapDecoder bmpDec = BitmapDecoder.Create(new Uri(op.FileName), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
BitmapSource bsource = bmpDec.Frames[0];
info_box.Content = fe;
imgControl.Source = bsource;
}
This work only with the raw codecs installed and dont work with ARW format.

If you don't have a codec installed, then you'll have to read the raw image data and convert it to a bitmap or other format that you can read. In order to do that, you need a copy of the format specification so that you can write code that reads the binary data.
I strongly recommend getting a codec, or finding code that somebody has written that already handles the conversion. But if you really want to try your hand at writing image format conversion code, your first order of business is to get the format specification.
A quick Google search on [CR2 image format] reveals this Canon CR2 Specification. Truthfully, I don't know how accurate that is, but it looks reasonable. A little time with a search engine will probably reveal similar documents for the other formats.
Be forewarned: writing these conversions can be a very difficult task. Again, I recommend that you find some existing code that you can leverage.

If you insist on not installing a codec, then your best bet might be these:
http://www.cybercom.net/~dcoffin/dcraw/
- written in C, supports most cameras
http://sourceforge.net/projects/dcrawnet/
- apparently a (partial?) port of DCRAW to C#, but project does not seem to be active

Related

Convert iTextSharp.text.pdf.BarcodeQRCode to System.Drawing.Image

Looking for a way to convert iTextSharp.text.pdf.BarcodeQRCode to System.Drawing.Image
This is what I have so far...
public System.Drawing.Image GetQRCode(string content)
{
iTextSharp.text.pdf.BarcodeQRCode qrcode = new iTextSharp.text.pdf.BarcodeQRCode(content, 115, 115, null);
iTextSharp.text.Image img = qrcode.GetImage();
MemoryStream ms = new MemoryStream(img.OriginalData);
return System.Drawing.Image.FromStream(ms);
}
In line 3 above using img.OriginalData returns null
Using img.RawData on line 3 instead thows invalid parameter error on line 4.
I've googled some of the code samples on how to perform the thing you want and your code (the "OriginalData" approach) is basicaly the same: https://csharp.hotexamples.com/examples/iTextSharp.text.pdf/BarcodeQRCode/-/php-barcodeqrcode-class-examples.html .
However, I don't see how it could work. From my investigations of BarcodeQRCode#getImage it seems that OriginalData is not set while processing such a barcode, so it will always be null.
More than that, the code you mention belongs to iText 5, which is end of life and no longer maintained (with an exception of considerable security fixes), so it's recommended to update to iText 7.
As for iText 7, I do see how to achieve the same in Java, since barcode classes do have a createAwtImage method there. .NET, on the other hand, lacks such a functionality, so I'd day that one unfortunately couldn't do it in .NET.
There are some good reasons for that. iText's Images (and a barcode could be easily converted to an iText's Image object as shown here: https://kb.itextpdf.com/home/it7kb/faq/how-to-generate-2d-barcode-as-vector-image) represent a PDF's XObject. In PDF syntax, an image file (jpg, png, etc.) is an XObject with the raw image data stored inside. However, an XObject can also contain PDF syntaxt content (it is not just used for image files). So to render such a content one needs to process the data from PDF syntax to image syntax, which is not that easy. There are some means in Java's awt to do so, that's why it's implemented in Java. As for .NET, since there is no out-of-the-box means to convert PDF images to System.Drawing.Image, it was decided not to implement it.
To conclude, there is another iText product, pdfRender, which allows one to convert PDF files (and you could create a page just for a barcode) to images. Perhaps you might want to play with it: https://itextpdf.com/en/products/itext-7/convert-pdf-to-image-pdfrender

Reduce the size of the PNG image

I want to compress PNG image
I am using below code: (Below code is working fine for jpeg,jpg) but not for png.
var qualityParam = new EncoderParameter(Encoder.Quality,80);
// PNG image codec
var pngCodec = GetEncoderInfo(ImageFormat.Png);
var encoderParams = new EncoderParameters(1) { Param = { [0] = qualityParam } };
rigImage.Save(imagePath, pngCodec, encoderParams);
private static ImageCodecInfo GetEncoderInfo(ImageFormat format)
{
// Get image codecs for all image formats
var codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
return codecs.FirstOrDefault(t => t.FormatID == format.Guid);
}
JPEG "works fine" because it can always discard more information.
PNG is a lossless image compression format, so getting better compression is trickier and there's a pretty high "low mark". There are tools like PNGOut or OxiPNG which exist solely to optimise PNG images, but most strategies are very computationally expensive so your average image processing library just doesn't bother:
you can discard irrelevant metadata chunk
you can enumerate and try out various filtering strategies, this amounts to compressing the image dozens of time with slightly different tuning and checking out the best
you can switch out the DEFLATE implementation from the default (usually the stdlib or system's standard) to something better but much more expensive like zopfli
finally — and this one absolutely requires human eyeballs — you can try and switch to palletised
As noted above, most image libraries simply won't bother with that, they'll use a builtin zlib/deflate and some default filter, it can takes minutes to make a PNG go through an entire optimisation pipeline, and there's a chance the gain will be non-existent.
As #Masklinn said, PNG is a lossless format, and I think the BCL in .NET does not have an API that can help you to "optimize" the size of the PNG.
Instead, you could use the libimagequant library; you can get more information about this library here, and how to use it from .NET here.
This is the same library used by PNGoo, I have got really impressive results with it when optimizing PNGs in my projects.
Also, if you are planning to use the library in a commercial project, keep in mind the license terms, as indicated at https://pngquant.org/lib/.

How to remove metadata from jpg and png images

This should be a pretty trivial programming task in C#, however after I have searched a while I simply cannot find anything relevant on how to remove metadata.
I want to remove jpg and png image metadata such as: folder path, shared with, owner and computer.
My application is an MVC 4 application. In my website users can upload an image I get this image at this ActionResult method
if (image != null)
{
photo.ImageFileName = image.FileName;
photo.ImageMimeType = image.ContentType;
photo.PhotoFile = new byte[image.ContentLength];
image.InputStream.Read(photo.PhotoFile, 0, image.ContentLength);
}
Photo is a property in the model, goes like this.
public byte[] PhotoFile { get; set; }
I imagine the way to remove above mentioned metadata or just all metadata, would be to use some coding like this
if (image != null)
{
image = image.RemoveAllMetaData; !!!
I dont mind using some 3rd party dll as long as it is compatible with NET 4.
Thanks.
'Metadata' here is a bit ambiguous--Do you mean the data which is required for a viewer to properly determine the image format so it can be displayed, saving only the raw image data? Or, more likely, do you mean the extra information, such as author, camera type, GPS location, etc, that is often added via the EXIF tags?
If you mean something like the EXIF data, there's a lot of programming material already on the web about how to add/modify/remove EXIF tags, and even some apps which already strips such tags: http://www.steelbytes.com/?mid=30 for example.
If you mean you just want the raw image data, you'll probably have to read and process the image first, since both JPEG and PNG do not contain simply the raw image data; It's encoded with various methods--which is why they contain metadata to tell you how to decode it in the first place. You'll have to learn/explore the JPEG and PNG data formats to extract the original raw image data (or a reasonable facsimile in the case of a "lossy" encoding).
All the above is well-documented on various websites which can be found on Google, and many include image manipulation libraries which can handle these chores for you. I suspect you just didn't know to search for something like "JPEG PNG EXIF METADATA".
BTW, EXIF applies to JPEG's, where EXIF is, loosely (and not fully technically correct) an addition of data (extension) to the end of the JPEG file, which can usually simply be truncated to remove. A quick Google search for me turned up something like libexif.sourceforge.net and other similar results.
I'm not entirely certain about the PNG format, but I believe the PNG format (which does call such items "metadata" as well) was written to include such data as part of the file format rather than an "extension" tagged on after the fact like EXIF is. PNG, however, is open source, and you can obtain libraries and code for manipulating them from the PNG website (www.libpng.org).
There's an app for that but it's written in Perl. It doesn't recompress the image and it's here http://www.sno.phy.queensu.ca/~phil/exiftool
Found it in this thread
How to remove EXIF data without recompressing the JPEG?
Do what all the social media websites do. Create a new image file, stream in the image byte data and use the file you created than the original one that was uploaded. Of course, now you will need to find out the original image's color depth and so on so that the image you create is not of a lower quality -- unless you need to do a disk or image resize as well.

Raise wave file volume with NAudio

I am an audio noob
I am looking to embed audio in an html page by passing the data as a string such as
< Audio src="data:audio/wav;base64,AA....." />
doing that works, but I need to raise the volume. I tried working with NAudio but it seems like it does some conversion and it will no longer play. This is the code I use to raise the volume:
public string ConvertToString(Stream audioStream)
{
audioStream.Seek(0,SeekOrigin.Begin);
byte[] bytes = new byte[audioStream.Length];
audioStream.Read(bytes,0,(int)audioStream.Length);
audioStream.Seek(0,SeekOrigin.Begin);
return Convert.ToBase64String(bytes);
}
var fReader = new WaveFileReader(strm);
var chan32 = new WaveChannel32(fReader,50.0F,0F);
var ouputString = "data:audio/wav;base64," + ConvertToString(chan32);
but when I put outputString into an audio tag it fails to play. What type of transformation does NAudio do, and how can I get it ton give me the audio stream in such a way that I can serialize it and the browser will be able to play it?
Or for another suggestion: if NAudio to heavyweight for something as simple as raising the volume what's a better option for me?
I'm no expert in embedding WAV files in web pages (and to be honest it doesn't seem like a good idea - WAV is one of the most inefficient ways of delivering sound to a web page), but I'd expect that the entier WAV file, including headers needs to be encoded. You are just writing out the sample data. So with NAudio you'd need to use a WaveFileWriter writing into a MemoryStream or a temporary file to create a volume adjusted WAV file that can be written to your page.
There are two additional problems with your code. One is that you have gone to 32 bit floating point, making the WAV file format even more inefficent (doubling the size of the original file). You need to use the Wave32To16Stream to go back to 16 bit before creating the WAV file. The second is that you are multiplying each sample by 50. This will almost certainly horribly distort the signal. Clipping can very easily occur when amplifying a WAV file, and it depends on how much headroom there is in the original recording. Often dynamic range compression is a better option than simply increasing the volume.

Compressing a TIF file

I'm trying to convert a multipage color tiff file to a c# CompressionCCITT3 tiff in C#. I realize that I need to make sure that all pixels are 1 bit. I have not found a useful example of this online.
You need this conversion as CCITT3 and CCITT4 don't support color (if I remember right).
Pimping disclaimer: I work for Atalasoft, a company that makes .NET imaging software.
Using dotImage, this task becomes something like this:
FileSystemImageSource source = new FileSystemImageSource("path-to-your-file.tif", true); // true = loop over all frames
// tiff encoder will auto-select an appropriate compression - CCITT4 for 1 bit.
TiffEncoder encoder = new TiffEncoder();
encoder.Append = true;
// DynamicThresholdCommand is very good for documents. For pictures, use DitherCommand
DynamicThresholdCommand threshold = new DynamicThresholdCommand();
using (FileStream outstm = new FileStream("path-to-output.tif", FileMode.Create)) {
while (source.HasMoreImages()) {
AtalaImage image = source.AcquireNext();
AtalaImage finalImage = image;
// convert when needed.
if (image.PixelFormat != PixelFormat.Pixel1bppIndexed) {
finalImage = threshold.Apply().Image;
}
encoder.Save(outstm, finalImage, null);
if (finalImage != image) {
finalImage.Dispose();
}
source.Release(image);
}
}
The Bob Powell example is good, as far as it goes, but it has a number of problems, not the least of which is that it's using a simple threshold, which is terrific if you want speed and don't actually care what your output looks like or your input domain is such that really is pretty much black and white already - just represented in color. Binarization is a tricky problem. When your task is to reduce available information by 1/24th, how to keep the right information and throw away the rest is a challenge. DotImage has six different tools (IIRC) for binarization. SimpleThreshold is bottom of the barrel, from my point of view.
I suggest to experiment with the desired results first using tiff and image utilities before diving into the coding. I found VIPS to be a handy tool. The next option is to look into what LibTIFF can do. I've had good results with the free LibTiff.NET using c# (see also stackoverflow). I was very disappointed by the GDI tiff functionality, although your milage may vary (I need the missing 16-bit-grayscale).
Also you can use the LibTiff utilities (i.e. see http://www.libtiff.org/man/tiffcp.1.html)
I saw the above code, and it looked like it was converting every pixel with manual logic.
Would this work for you?
Imports System.Drawing.Imaging
'get the color tif file
Dim bmpColorTIF As New Bitmap("C:\color.tif")
'select the an area of the tif (will grab all frames)
Dim rectColorTIF As New Rectangle(0, 0, bmpColorTIF.Width, bmpColorTIF.Height )
'clone the rectangle as 1-bit color tif
Dim bmpBlackWhiteTIF As Bitmap = bmpColorTIF.Clone(rectColorTIF, PixelFormat.Format1bppIndexed)
'do what you want with the new bitmap (save, etc)
...
Note: there are a ton of pixelformats to choose from.

Categories