How to create anti-aliased text on a Bitmap with ExtTextOut? - c#

In my WinForm app I draw into a System.Drawing.Bitmap. I create fonts from a LOGFONT and draw using the GDI function ExtTextOutW. However the output is terrible. It has bad jaggies and looks like the antialiaser was on LSD. Reading around this seems a common issue - is there a resolution?
If I use:
lf.lfQuality = FontQuality.NONANTIALIASED_QUALITY
when I create the font then the horrible jaggies go away but of course there is no antialiasing.
Is there a way to create smooth text in a Bitmap with ExtTextOutW?

It is possible but a bit tricky and it can't have transparent background.
You will need to:
Create in-memory bitmap buffer that is compatible with display device context (IntPtr.Zero handle)
Fill the buffer background with solid color or other background
Render the text into the memory bitmap
Copy from in-memory bitmap to image device context (BitBlt)
See GDI text rendering to image for more details.

Related

Turning graphics into bitmap in c#

So I've been struggling with this for a while. How can I turn a graphic that I drew into a bitmap and how can I keep it updated? I mean let's say I wanna draw some shapes and then go ahead and color some random areas using setPixel, getPixel etc by going pixel by pixel on the bitmap. I don't want the old drawings to dissapear, but to put the color on top of it if it makes sense. And also, how can I save the bitmap on the computer without getting just a black image?
I'm relatively new to c# and getting answers to these questions would mean the world to me.
To save a Bitmap is easy
Bitmap pic = new Bitmap(16, 16);//16x16 picture
//draw what you want
pic.Save("name.bmp");//save the drawed Bitmap
pic.Dispose();
With .Save you save the file.
With .Dispose you give the ressourses free from the picture, dispose the picture when you don't use the picture anymore.

RichTextBox: Transparent Background vs. Font Quality in Bitmap

I created a RTF control pretty similar to the one described here.
Works pretty fine. Sometimes i have the control draw its contents directly to the device context, sometimes i use an offscreen bitmap which i draw to the device context myself, depending on the situation.
Now i needed the control to have a transparent background so i've overriden the CreateParams method called on initalising the base clss and added createParams.ExStyle |= 0x20; which boils down to one of the extended window styles, WS_EX_TRANSPARENT.
At this point, transparency works like a charm. But in contrast to before, setting this option makes drawing to the offscreen bitmap unusable, since the font quality suffers. Note, that only when drawing to the bitmap the font quality turns bad, drawing to the device context of the control is still working although creating the offscreen bitmap uses the same routines, just with a different device context.
As you can see, the font on the left is perfectly fine, while on the right side, the font get messy, too bold and it seems like it's drawn over several times with the coordinates not matching.
Commenting out the line added for transparency makes the bitmap return to normal but also yields in a white background for everything drawn, making me loose transparency.
Any ideas how to get a successfull combination of the two desired effects?

Rendering a specific region of a BufferedGraphics buffer

I need to render a large PDF document into a Windows form control. For this to be performant, it would make sense to prerender the entire PDF into a graphics buffer and then blit the relevant part of that buffer in OnPaint.
However, BufferedGraphics.Render does not accept any arguments other than the target Graphics. How can I make it only render a certain region?
Use the bounding Clip on the Graphics
MSDN Graphics.Clip Property
Another option is to Import the old BitBlt function.

How to display scaled image without anti-aliasing?

Question
How can I scale an image in XAML quickly without anti-aliasing applied?
Background
I am trying to make a pixel editor as a Windows 8 XAML/C# app. I'm using c#/XAML because most of my experience is with c#/WPF.
Method 1: WriteableBitmap + Image control. Originally, I used a WriteableBitmap to store and edit an image. That image is displayed in a resized XAML Image control. The problem is that the image does not get scaled properly because of anti-aliasing. (XAML does not seem to provide the BitmapScalingOptions that are available in WPF)
Method 2: Redrawn WriteableBitmap + Image control. Next I tried writing my own scaling, where I take my original image and write to a larger WriteableBitmap so that the scaled image is pixelated. The scaled image is then presented inside a XAML Image control. This process is slow and inefficient.
Method 3: SharpDX + Direct2d ?? I am pretty sure a solution exists somewhere between SharpDx, SurfaceImageSource, and Direct2d. Event still, I can't quite figure out how to display a SharpDx.WIC.Bitmap inside a Windows.UI.Xaml Image control, and am generally getting lost in the documentation.
What exactly is a recommended setup for achieving my desired end? Are there c# samples available which might point me in the right direction?
I don't know if you mean by scaling it by resizing it with the mouse or just with a button click to auto scale to a predetermined size.
But the thing you can do is to use an Image panel and then, just set it to image.Stretch = Stretch.Fill; so if you override and create a method for the Resize event of the Image Panel, your image will take the size to fill the Image panel.

Adding whitespace to the top of an image using a given hDC

The Layout:
I'm using third party controls to scan documents. I have an event that occurs when I scan an image (mostly used to add annotations the image). The event provides me with only one property named .PAhDC. This property is a handle to the DC that stores the image before it is written to a file. Thus I can make changes to the image before it gets written to a file.
The Expected Results:
I would like to simply add a 1/4 inch (lets say 100 pixels) of white space line on the very top of the image. If my original image is 200x200 (WxH) then my new final image would need to be 200x300.
Question And Other Thoughts:
How can I alter an existing image with only knowing it's DC handle? I was thinking of doing something like the following...
Create a new DC.
Create a new Bitmap 100 pixels taller than the original image.
Use that new bitmap in the new DC.
Copy the original image to the new bitmap (100 pixels from the top as a start point).
Then use something like SelectObject to replace the old bitmap in the original hDC with the new one and then destroy the old bitmap object.
Note: I would like to do this with MANAGED CODE as much as possible. Using SelectObject() was the only way I could think of but it's of course unmanaged code... :/
You can't without cooperation with the owner of the bitmap and DC.
The DeviceContext is purely a viewport onto an underlying DIB/bitmap and has no concept of size or dimensions (beyond the clipping region) While you can create a new bitmap and select it into the DC, it's highly likely that the application will just ignore what you've done and use the DIB that it has created.
The end result of this will be GDI object leaks and no change to the underlying image.
To do what you you ask, you will need full cooperation with the other code and them adding a method that allows you to replace the underlying data.
Sure, you can do this in managed code. All P/Invoke declarations are readily available from any decent search engine.
When creating a new DC, make sure it's a DC compatible with the original one
When creating a new bitmap, make sure it's compatible with the DC

Categories