LibTiff.Net color image conversion - c#

I am using Bit Miracle LibTiff.Net.
I cannot find any sample code to take a 32bpp ARGB colour image and write the bitmap to a TIFF using this library.
Has anyone else attempted this?
Here is my sample code. It produces a file, but it cannot be viewed by any software that I have.
EDIT: The code now works, but the colors are wrong!
public static void WriteTiff(Image image, string fileName)
{
Bitmap target = image as Bitmap;
BitmapData bmd = target.LockBits(
target.GetRectangle(),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
var bits = new byte[bmd.Stride * bmd.Height];
Marshal.Copy(bmd.Scan0, bits, 0, bits.Length);
target.UnlockBits(bmd);
Tiff tiff = Tiff.Open(fileName, "w");
tiff.SetField(TiffTag.IMAGEWIDTH, target.Width);
tiff.SetField(TiffTag.IMAGELENGTH, target.Height);
tiff.SetField(TiffTag.COMPRESSION, Compression.NONE);
tiff.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB);
tiff.SetField(TiffTag.BITSPERSAMPLE, 8);
tiff.SetField(TiffTag.SAMPLESPERPIXEL, 4);
tiff.SetField(TiffTag.ROWSPERSTRIP, target.Height);
tiff.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
tiff.WriteEncodedStrip(0, bits, bits.Length);
tiff.Close();
}
Thanks

EDIT
The latest build of LibTiff.Net contains samples for conversion of a System.Drawing.Bitmap to 32-bit or 24-bit color LZW compressed TIFF images.
There is also samples for conversion of a TIFF image to 32-bit or 24-bit System.Drawing.Bitmaps.
/EDIT
You may also want to review "Graphics programming with LibTiff.Net" (part 1, part 2) article
in documentation. It should give you basic information about creating
color TIFF files.
Disclaimer: I am one of the maintainers of the library.

Related

Can Graphics.DrawImage draw a YV12 DIB?

I've inherited a C# .Net Windows Forms project which receives a Device Independent Bitmap (as an array of bytes) from a Managed pre-compiled DLL. The C# code makes a dummy BMP file from the DIB so that it can create a Bitmap which can then be drawn using System.Drawing.Graphics.DrawImage.
using (MemoryStream ms = new MemoryStream())
{
ms.Write(fileHeader, 0, fileHeader.Length);
ms.Write(dibBuffer, 0, dibBuffer.Length);
Bitmap img = (Bitmap)Image.FromStream(ms);
g.DrawImage(img, 0, 0, width, height);
}
This works when the DIB contains uncompressed pixel data but on some hardware, the pixel data is in YV12 format and Image.FromStream raises a System.ArgumentException which I think indicates that the underlying code (GDI+?) considers the BMP to be in an invalid or unsupported format.
In this scenario, the DIB's BITMAPINFOHEADER (first 40 bytes) has these values:
biSize: 40
biWidth:640
biHeight: 480
biPlanes: 1
biBitCount: 12
biCompression: 'YV12'
biSizeImage: 460800
biXPelsPerMeter: 0
biYPelsPerMeter: 0
biClrUsed: 0
biClrImportant: 0
Does the BMP format even support YV12? I can't find any example
images online.
Is there a different way of handling the DIB to make it suitable for
DrawImage? The above code seems to jump through hoops.

Save .jpg image in grayscale using C# [duplicate]

We have a system that provides images in 8-bit grayscale either tiff or jpg formats. However, the component we have to process the images expects image to be in 8-bit jpg format.
When I use .Net to save the tiff images as jpg it convets it to 24-bit image.
Is there a way, hopefully simple and fast, to convert 8-bit grayscale tiff images to equivalent jpg?
I tried and tried just to conclude that I'm sorry: .Net library's Bitmap class DOES NOT save JPEG as 8bpp even when explicitly stated and data is in grayscale.
(note: although stated in some places, JPEG format DOES support 8bpp).
At Convert an image to grayscale you may find code snipet to convert to grayscale any Image.
Using that code, I was able to save a 8bpp grayscale Image instance with '.jpeg' extension, but stating ImageFormat.Gif... that's a cheat...
My findings show as solution an entirely different approach.
The FreeImage library offers powerful APIs, including the feature needed to solve your problem.
It's home page is at http://freeimage.sourceforge.net/faq.html
But, I could not easily compile it in my Win2008 + VS 2010 machine.
One ought to sweat a lot to make it run on modern environments.
Some hints on how to accomplish that are found at http://www.sambeauvois.be/blog/2010/05/freeimage-and-x64-projects-yes-you-can/
Good luck!
Image img = Image.FromFile(filePathOriginal);
Bitmap bmp = ConvertTo8bpp(img);
EncoderParameters parameters = new EncoderParameters();
parameters.Param[0] = new EncoderParameter(Encoder.ColorDepth, 8);
bmp.Save(filePathNew, jpgCodec, parameters);
bmp.Dispose();
img.Dispose();
...
private static Bitmap ConvertTo8bpp(Image img) {
var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);
using (var gr = Graphics.FromImage(bmp))
{
gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height));
}
return bmp;
}

Extrating image information about a PNG in .NET

I'm trying to get information about a PNG file but I've yet to discover a comprehensive site to help me.
These are some of the semi useful code snippets I have:
Bitmap bmp = new Bitmap(pngFileName);
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly,PixelFormat.Format48bppRgb);
and
Stream imageStreamSource = new FileStream(pngFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
var decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
With these I've been able to to get the image height and width. However I still need to discover the following information:
Is it RLE encoded?
Is it in native video format?
Is it rotated?
Does it use a grayscale palette?
Does it have a transparency?
Is it RGB or BGR?
I'd really appreciate some pointers on how to acheive this or links to good articles dealing with this. We're working with .NET 4.0
I'm not sure if that helps you, but the best I've seen so far, is to walk the image pixel by pixel in a loop and accomplish your different tasks.
See these answers for examples:
Detecting if a PNG image file is a Transparent image?
Detecting grayscale images with .Net

Basics in Resizing Pictures or What happened to Picture Size?

I am writing a program that resizes pictures like this:
Image originalImage = Image.FromFile(pathToOriginalPicture);
Bitmap b = new Bitmap(newWidth, newHeight);
Graphics g = Graphics.FromImage(b);
g.DrawImage(originalImage, 0, 0, newWidth, newHeight);
g.Dispose();
b.Save(pathToOutputPicture, ImageFormat.Jpeg);
I tried to set:
newWidth = originalImage.Width;
newHeight = originalImage.Height;
The result was that the rezised picture file became ~900K while the original file was ~4M.
Why this is happening ?
Is the quality of the original picture better than the resized one ? How?
I opened both pictures in Photoshop and I see that the original picture was 72ppi, while the resized one became 96ppi. Why is that ? Can I control this ?
Thanks a lot for your time !
You're not telling us the original format of your picture but you're saving as a JPEG:
b.Save(pathToOutputPicture, ImageFormat.Jpeg);
JPEG is a lossy compression format.
In addition to being lossy, JPEG also can output different quality (which is configurable).
This is what is happening to your file size: it is shrinking because you went, say, from a lossless format to the lossy JPEG or because you went from JPEG to JPEG-with-a-lower-quality.
Hence the size reduction.
Besides the format you need to set DPI, compression level settings etc. Check your Save function for overloads that will accept this type of input. See this documentation.

C# why resize image will increase the file size

I have image file which is 6k jpg file with width: 172px and hight: 172px.
I use the following code try to resize it to 128*128px jpg file:
public static Image ResizeImage(Image img, int width, int height)
{
var b = new Bitmap(width, height, PixelFormat.Format24bppRgb);
using (Graphics g = Graphics.FromImage(b))
{
g.DrawImage(img, 0, 0, width, height);
}
return b;
}
This code has strangely increased the file size to 50k, can any one explain why? and how to resize the image to 128*128px and keep the size about 6k.
Many thanks.
DY
It depends on the algorithm that was used to compress the jpeg file. Certain algorithms are more lossy (lose image quality) than others but benefit from a smaller size.
What's happening is that in code, the jpeg is being expanded into a bitmap while in memory. When it went to save the 128x128 jpeg out, the code used an algorithm which does less compressing than the one used to save the original picture. This caused it to produce a larger jpeg file, even though the image size itself is smaller.
In the code posted, you are not returning JPEG file, but bitmap (128x128 24bpp uncompressed bitmap has size 48kB). You have to compress it again, this tutorial might help.

Categories

Resources