This seems to be the standard method to convert the pixel format of a bitmap but it's giving me a very poor result when converting to black and white format:
// convert to black & white bitmap
FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(bitmap, PixelFormats.BlackWhite, null, 0);
// save black & white bitmap to file
fileName = string.Format("{0}.bmp", data.SelectedProduct.Code);
bitmapEncoder = new BmpBitmapEncoder();
bitmapEncoder.Frames.Add(BitmapFrame.Create(monoBitmap));
using (Stream stream = File.Create(fileName))
{
bitmapEncoder.Save(stream);
}
The resulting image file is very grainy and pixelated. I need to send it to a line printer so I need sharp edges.
The original before conversion looks fine (its 32BPP color) and if I use something like IrfanView to manually convert the original to black and white it also comes out much better than whatever .NET is doing.
Is there another alternative for doing this in .NET instead of FormatConvertedBitmap?
It are using PixelFormats.BlackWhite, which uses only black and white colors in the resulting image, which probably can make it look grainy if there are light pixels surrounded by darker ones. I suppose the effect can be better, if you convert the image to use the shades of gray. In order to do this, you this line of code instead of the one in the code you've posted:
FormatConvertedBitmap monoBitmap = new FormatConvertedBitmap(bitmap, PixelFormats.Gray32Float, null, 0);
This should convert the image to use only only shades of gray, so no color will be needed to print it.
Let me know if it's the effect you want to achieve.
You can find some more information about PixelFormats class here: http://msdn.microsoft.com/en-us/library/system.windows.media.pixelformats.aspx.
Related
I need to write in a form using a bitmap font at a specific point size, without having Windows do any antialiasing or otherwise "helping" the display of the text. The reason is that the text will be saved out as a bitmap for display on a low-resolution display (eg a Netduino-driven bitmap with space for 120 pixels wide and 40 pixels high) , so if I want a black "A" on the screen I can't have grey pixels added in and arund the letters.
I need to use a font like this
http://robey.lag.net/2010/01/23/tiny-monospace-font.html
Although I know Windows doesn't do BDF I included that as a reference to the kind of no-nonsense super small typeface that I need to use in Windows.
Using C#, Franework 4.5.2, what can I do to make .NET emit a typeface as a pure unscaled bitmap?
I built a bitmap using the "Tiny" TrueType font at 6 point. Notice in the generated bitmap image that the text is all not pure white, although I specified it that way.
using (var gb = Graphics.FromImage(mybitmap))
{
gb.PixelOffsetMode = PixelOffsetMode.Half;
gb.SmoothingMode = SmoothingMode.None;
gb.InterpolationMode = InterpolationMode.NearestNeighbor;
gb.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
gb.TextContrast = 0;
gb.Clear(colorbg);
var fontSize = Convert.ToSingle(6);
var nowFont = new Font( myfont , fontSize, GraphicsUnit.Pixel );
TextRenderer.DrawText(gb, "pack my box..." , nowFont , new Point(0, 0), colorforeground);
}
Thanks.
Set the Graphics.TextRenderingHint property to TextRenderingHint.SingleBitPerPixelGridFit. If the font has no TrueType hinting at all then SingleBitPerPixel is probably your preferred choice. Either renders text without any anti-aliasing.
I want to detect an Eye, I have some code where I can detect blue color object, so if I made changes(how I can?) then it would be possible for me to detect an eye. As the below color has its own specific range value so, if I specify the eye color HSV value then can I detect EYE with this method.
In this below code I am going to detect BLUE Color Object, please tell me that where I do changes in my code so that I could get EYE using Open CV.
IplImage* GetThresholdedImage(IplImage* img)
{
// Convert the image into an HSV image
IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3);
cvCvtColor(img, imgHSV, CV_BGR2HSV);
IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1);
//For detecting BLUE color i have this HSV value,
cvInRangeS(imgHSV, cvScalar(112, 100, 100), cvScalar(124, 255, 255), imgThreshed);//this will not recognize the yellow color
cvReleaseImage(&imgHSV);
return imgThreshed;
}
Eye detection is much easier with Haar classifier.
link here
Such a simple method may work at extracting a blue object using some thresholding but even if it could be adapted using a different colour black? blue? green? Everyone has different eye colours. I don't see a non hacky method working for you using blob extraction like this based on a HSV threshold value. This method works well on large blocks of the same colour, i.e. removing a blue background.
Look more at shape, everyone has different coloured eyes but the shape is circular/ellipse ish. There are varients of the Hough Transform for detecting circles.
...the Hough transform has been extended to identifying positions of
arbitrary shapes, most commonly circles or ellipses.
Following is a snippet of a simple code to convert a grayscale image to RGB using cvCvtColor function in OpenCV.
input = cvLoadImage("test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
output = cvCreateImage(cvSize(input->width, input->height), 8, 3);
cvCvtColor(input, output, CV_GRAY2BGR);
cvSaveImage("output.jpg", output);
Where test.jpg is a grayscale image.
But it doesn`t seem to be working properly, because output.jpg i.e the final output also is grayscale, same as the input itself. Why so ?
Any kind of help would be highly appreciated. Thanks in advance !
I think you misunderstand cvCvtColor. cvCvtColor(input, output, CV_GRAY2BGR); will change single channel image to 3-channel image. But if you look at the image, it will still look like a gray image because, for example, a gray pixel of 154 has been converted to RGB(154,154,154).
When you convert color image to gray image, all color information will be gone and not recoverable. Therefore you can't really make a gray image to visibly color image without additional information and corresponding operations.
I have a basic png file with two colors in it, green and magenta. What I'm looking to do is to take all the magenta pixels and make them transparent so that I can merge the image into another image.
An example would be if I have an image file of a 2D character on a magenta background. I would remove all the magenta in the background so that it's transparent. From there I would just take the image of the character and add it as a layer in another image so it looks like the character has been placed in an environment.
Thanks in advance.
That's the code i would use,
First, load your image :
IplImage *myImage;
myImage = cvLoadImage("/path/of/your/image.jpg");
Then use a mask like this to select the color, you should refer to the documentation. In the following, I want to select a blue (don't forget that in OpenCV images are in BGR format, therefore 125,0,0 is a blue (it corresponds to the lower bound) and 255,127,127 is blue with a certain tolerance and is the upper bound.
I chose lower and upper bound with a tolerance to take all the blue of your image, but you can select whatever you want...
cvInRangeS(image,
cvScalar(125.0, 0.0, 0.0),
cvScalar(255.0, 127.0, 127.0),
mask
);
Now we have selected the mask, let's inverse it (as we don't want to keep the mask, but to remove it)
cvNot(mask, mask);
And then copy your image with the mask,
IplImage *myImageWithTransparency; //You may need to initialize it before
cvCopy(myImage,myImageWithTransparency,mask);
Hope it could help,
Please refer to the OpenCVDocumentation for further information
Here it is
Julien,
I'm trying to save a Visual object, which has a transparent background, to a bitmap using RenderTargetBitmap...
public static RenderTargetBitmap RenderToBitmap(this Visual Source, int Width, int Height)
{
var Result = new RenderTargetBitmap(Width, Height, 96, 96, PixelFormats.Default);
Result.Render(Source);
return Result;
}
It works, but the transparent pixels are rendered with black color.
What the simplest way to change these transparent pixels to another color?
If you are saving the image as a JPG, transparent will appear black since JPG does not support transparent channel AFAIK. Possible solution: save as a PNG, or paint with a reasonable background color.
I haven't tested this, but in theory it should work.
Use the CopyPixels() method to extract all the pixel data from your RenderTargetBitmap to an array.
Then query the Alpha channel of all those pixels and where they are equal to 0x00 (fully transparent), set the color to whatever you'd like in the background. If you want to be more elegant, you'd have to do the "color math" to properly set the colors in semi-transparent pixels.
Finally, after you have an adjusted array of pixels, create a new BitmapSource from them.
To save that to disk, you'll probably have to create an Image in memory and set its Source to your new Bitmapsource and run your RenderToBitmap again.
Hope it helps.
EDIT:
After posting this, I had
another thought that may be easier.
If you take a clone or snapshot of the
visual element you're trying to save
and put it into a new in-memory panel
(such as a grid or a canvas), you
could simply change the background of
the panel to be the color you want.
Then you'd use the panel as your
source for RenderTargetBitmap.