C# Convert indexed pixel to new file bit32 - c#

Does anybody have a sample code on how i could open a tif file, copy it out to a new locate from indexed pixel to new bitmap 32?
I found this http://fci-h.blogspot.com/2008/02/c-indexed-pixel-problem.html But i'm to new to piece it together. Is there a possible way to just read this all in memory without actually creating a new file?
What I mean is this. I have to find the original file (which i already got). Copy the file to a temp location (which I got). What I don't understand is how when I copy that new file I need to keep the original size and give the new file a bitmap of 32.
I can't draw an image over the picturebox because C# doesnt really support indexed pixels.

Bitmap newImage = new Bitmap(original);
This will make your newImage start with the contents of original. The difference will be that you will end up with newImage.PixelFormat == PixelFormat.Format32bppArgb, regardless of original.PixelFormat.

This does what you want I think...
If you dont need to save it, just work with 'bm' after you do the DrawImage, that is your image as a Bitmap...
Bitmap bm = (Bitmap)System.Drawing.Image.FromFile("TifFilePath.tif", true);
Bitmap tmp = new Bitmap(bm.Width, bm.Height);
Graphics grPhoto = Graphics.FromImage(tmp);
grPhoto.DrawImage(bm, new Rectangle(0, 0, tmp.Width, tmp.Height), 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel);
bm.Save("JPGFilePath.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
grPhoto.Dispose();

Related

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;
}

Converting Bitmap to GDK# PixBuff

How can I convert a System.Drawing.Bitmap to GDK# Image so that I can set to the image widget.
I have tried this...
System.Drawing.Bitmap b = new Bitmap (1, 1);
Gdk.Image bmp = new Gdk.Image (b);
UPDATE:
Bitmap bmp=new Bitmap(50,50);
Graphics g=Graphics.FromImage(bmp);
System.Drawing.Font ff= new System.Drawing.Font (System.Drawing.FontFamily.GenericMonospace, 12.0F, FontStyle.Italic, GraphicsUnit.Pixel);
g.DrawString("hello world",ff,Brushes.Red,new PointF(0,0));
MemoryStream ms = new MemoryStream ();
bmp.Save (ms, ImageFormat.Png);
Gdk.Pixbuf pb= new Gdk.Pixbuf (ms);
image1.Pixbuf=pb;
Exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> GLib.GException: Unrecognized image file format
at Gdk.PixbufLoader.Close()
at Gdk.PixbufLoader.InitFromStream(Stream stream)
at Gdk.PixbufLoader..ctor(Stream stream)
at Gdk.Pixbuf..ctor(Stream stream)
One ugly, but working, way is to store the bitmap as a PNG in a MemoryStream.
To save the Bitmap, you can use the Save method:
b.Save(myMemoryStream, ImageFormat.Png);
That was easy enough. Loading the PNG data into the Gdk# Pixbuf is also rather easy; you can use the appropriate constructor:
Pixbuf pb = new Gdk.Pixbuf(myMemoryStream);
You may need to reset the memory stream so the reading position is at the start of the stream before creating the Pixbuf.
A word of caution: I do not consider this the best, or even a "good" solution. Transferring data between two object-oriented data structures by serializing and deserializing the data has a certain code smell to it. I genuinely hope someone else can come up with a better solution.
EDIT: As for the used libraries: This answer uses only plain GDI+ (System.Drawing.Bitmap) and Gdk# (Gdk.Pixbuf). Note that a Gtk.Image is a widget that displays a Gdk.Pixbuf. As such, Gtk.Image is the equivalent of Windows Forms' PictureBox, whereas Gdk.Pixbuf is roughly equivalent to Windows Forms' System.Drawing.Bitmap.
EDIT2: After testing your code, I have found that there are three additional preconditions to ensure before you can run your minimum example:
As suspected above, you must reset the stream position to the beginning of the after saving your Bitmap and before loading your Pixbuf: ms.Position = 0;
You must compile the application for x86 CPUs.
You must invoke Gtk.Application.Init(); before you do anything with Pixbuf.
You may draw in Gtk# like in Winforms. For this you must obtain System.Drawing.Graphics object and then you may draw lines, images and text on it. You may do it like this: 1. Create new Widget. 2. Subscribe on ExposeEvent. 3. On event handler write some code:
protected void OnExposeEvent(object o, ExposeEventArgs e)
{
Gdk.Window window = e.Event.Window;
using (System.Drawing.Graphics graphics =
Gtk.DotNet.Graphics.FromDrawable(window))
{
// draw your stuff here...
graphics.DrawLine(new System.Drawing.Pen(System.Drawing.Brushes.Black), 0, 0, 30, 40);
}
}
Also you need to add reference on gtk-dotnet.dll.
try this ....
Gdk.Pixbuf pixbufImage = mew Gdk.Pixbuf(#"images/test.png");
Gtk.Image gtkImage = new Gtk.Image(pixbufImage);
Gdk.Image gdkImage = gtkImage.ImageProp;

Opening an image file to a Bitmap class as 32bppPArgb

Does .NET support PixelFormat conversions? I can't find any methods or constructors to do what I want.
I am allowing the user to choose any image file and I am creating a new Bitmap class from the file.
Then I am drawing the image using custom painting. It's very slow and I am told that the GDI is much faster dealing with images in the 32bppPArgb pixel format.
How do I perform the conversion? Assuming I have a string for the filename which could be a JPEG, TIF, PNG, etc., and I want to load it to a Bitmap class.
Edit:
Here is what I am trying to do, but it's not loading the image properly. The image is not filling the entire bitmap when I draw it.
using (Bitmap tempImage = new Bitmap(filename))
{
Image = new Bitmap(tempImage.Width, tempImage.Height, PixelFormat.Format32bppPArgb);
using (Graphics g = Graphics.FromImage(Image))
{
g.DrawImageUnscaled(tempImage, 0, 0);
}
}
If you have a scaling issue it is not caused by the pixel format. Instead, it is likely caused by DPI settings in the source image file. Try this instead of .DrawImageUnscaled:
g.DrawImage(
tempImage,
new Reactangle( Point.Empty, Image.Size ),
new Reactangle( Point.Empty, Image.Size ),
GraphicsUnit.Pixels );
That's what I always used instead of .DrawImageUnscaled - it has failed me too many times!

C# Image Edge Feathering

DISCLAIMER: This code is terrible and should not be used in production. It's testing a proof of concept.
I want to create an image like below using C# the key points are the feathered edges and the transparency of the whole image.
Here is my result so far
As you can see the edges are feathered. My question is, does anyone know how to feather the edges using pure C# and maintain transparency, currently I am using a 3rd party library with some pretty nasty looking code?
Would be interested if there is a better approach to this full stop.
Here is some of the code I have been using.
Bitmap bitmap = new Bitmap(width, height);
Graphics graphics = Graphics.FromImage(bitmap);
// Transparent Background
SolidBrush semiTransparentPen = new SolidBrush(Color.FromArgb(60, 31, 31, 31));
graphics.FillRectangle(semiTransparentPen, 0f, 0f, bitmap.Width, bitmap.Height);
// Feather edges
Bitmap bitmap1 = new Bitmap(bitmap);
Bitmap bitmap2 = new Bitmap(bitmap);
fipbmp.makeEdgesTransparentHorzSigma(bitmap1, 4, 4);
fipbmp.makeEdgesTransparentVertSigma(bitmap2, 4, 4);
fipbmp.MergeBmp(bitmap, bitmap1, bitmap2);
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Png);
byte[] buffer = memoryStream.ToArray();
You may find this blog post which I once wrote useful: Soft Edged Images in GDI+. That will show you a lot of what you need to know. In order to create smooth edges on an arbitrary shape you will also need a smoothing filter (which you'll then need to apply to the alpha channel), which you can read about here.

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.

Categories

Resources