My application acts as a document template with textboxes for users to fill in. Once they've completed, they can "print" the document to a PDF using PDFsharp. This is done by converting the panel on which the textboxes are on to a bitmap image using the code below;
ConditionReportConfig.PG1.Panel2.DrawToBitmap(Bitmap, New Rectangle(0, 0, Bitmap.Width, Bitmap.Height))
frm_MsgPrint.lbl_Page.Text = "Page: 1" : frm_MsgPrint.lbl_Page.Refresh()
frm_MsgPrint.PictureBox1.Image = Bitmap
frm_MsgPrint.PictureBox1.Refresh()
BXImage = Bitmap
GFX.ScaleTransform(0.82)
GFX.DrawImage(BXImage, 25, 0)
GFX.Dispose()
CDR1 = Nothing
Unfortunately, when the PDF pops up with the image the entire image, more so the text in the textboxes, are fuzzy. They aren't fuzzy to the point you can't read, but they do make reading the text incredibly stressful on your eyes.
I've tried adding various settings in such as;
Dim Bitmap2 = New Bitmap(894, 1367)
Using G As Graphics = Graphics.FromImage(Bitmap2)
G.InterpolationMode = Drawing2D.InterpolationMode.Bicubic
G.DrawImage(Bitmap, 0, 0, 120, 150)
End Using
I've even tried changing the font, size, even saving the bitmap as a TIFF, PNG and it still appears fuzzy. I would change printing methods, but the whole point of the panel is to be printed. Not only that but the panel contains images so I can't just print the text on the PDF.
Edit:
I've tried changing some of the interpolation settings, and it is slightly clearer but still a strain on your eyes.
Below is a snippet of the Bitmap image as a TIFF. Notice how the text in the textboxes is "Fuzzy" but the vertical text alongside is perfect. Is there really no way of getting textbox contents to be as sharp as the vertical text?
Blurry image with crystal clear vertical text:
Create an XImage from your bitmap and set
image.Interpolate = false;
for that image. This is a hint for Adobe Reader not to smooth the image.
Also check that ClearType does not make your image blurry before adding it to the PDF.
Related
I am trying to display a bitmap image to an OpenGL control called GL (I am using SharpGL as the wrapper). In practice, a text string is written to a GDI+ Picture box from which the Bitmap is obtained.
The GLBitmap function requires a Byte() array as input; I convert the Bitmap to a Byte() array. Does not seem to work as I get a bunch of dots on screen. I have also saved the PictureBox image to a Bmp file on disk and cross-checked that it had the desired content. So, the Bmp image does not appear to be the issue here.
Actual OpenGL display
Bmp file created from the code below
Wondering what I am doing wrong. Anybody would have a suggestion ? Thanks in advance.
The VB.Net code appears below.
' Create Bitmap & Graphics context for string
'
' iWidth and iHeight are the dimensions of the bitmap;
' they are a power of 2.
Dim SharpBMap As Bitmap = New Bitmap(iWidth, iHeight)
Dim SharpGraf As Graphics = Graphics.FromImage(SharpBMap)
' Draw text string to SharpGraf PictureBox
'
SharpGraf.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
SharpGraf.Clear(Color.White)
SharpGraf.DrawString(TxtStr, CurrFont, CurrBrush, 0, 0, CurrFormat)
' OutSharpGL is the Picture box to which the text string is sent
OutSharpGL.Image = SharpBMap
' Save the bitmap to disk: when the file is viewed, the image is Ok.
SharpBMap.Save(FilNameStr)
' Set the color
Gl.Color(1.0f, 1.0f, 1.0f)
' Set the Raster position
Gl.RasterPos(0, 0)
' Transfer the Bitmap
Gl.Bitmap(iWidth, iHeight, 0.0f, 0.0f, 0.0f, 0.0f, BitmapToByte(SharpBMap))
' Function to convert a Bitmap to a Byte() array
Friend Function BitmapToByte(ByRef Bmp As Bitmap) As Byte()
Dim converter As New ImageConverter()
Return DirectCast(converter.ConvertTo(Bmp, GetType(Byte())), Byte())
End Function
OpenGL requires raw pixel data ... BMP has encoding ...
In order to make this work you need to extract the raw pixel data from your BMP. That might be a bit too much to do correctly as there are a lot of format configurations out there ...
So make sure you change your bitmap to format that is easily handled like:
uncompressed
24 or 32 bpp
Now bitmap has a BMP header at its start describing the file is BMP and stuff like resolution, encoding, organization etc ... The header also usually holds the start address of the pixels... So extract that and pass the RAW pixels to your GL texture...
Beware BMP pixels are aligned on ScanLine basis so each line of image has some gap BYTE to align to certain multiple of size (usually 1..4 Bytes) you need to skip it and then process another line. Here related QA (but solved easily by VCL which is not your case)
How to get a pixel array from TBitmap?
However you need to do this on your own so you need:
dive into BMP fileformat
obtain resolution and pixel data start address from the header
construct your raw pixel data by copying the lines into yours memory array
skipping header and the align bytes
pass that as OpenGL texture
its faster to pass whole image than do it on per line basis. Beware you need to set the pixel format so it matches your raw data copied from bmp. So bpp must match and also the R,G,B order.
render textured quad
btw. much easier would be to print the texts directly in OpenGl. There are libs for that like FreeType but you can use textures instead like this:
GLSL debug prints
Of coarse CPU side GL text rendering using such texture is much easier than in GLSL. You just handle the texture as Texture Atlas where the Texture coordinates are computed from ASCII code and Texture font organisation.
I am trying to convert Multi-line Text to image but couldn't found a way to draw it with different Font format's is there any way to do it.Thanks in Advance.
What you could do is simply loading an image, and then setting it as the default graphics context, and then drawing text with a Graphics2D object using different fonts. Here's how you could do this :
BufferedImage image = ImageIO.load(new File("test.png"));
Graphics2D g2d = image.createGraphics();
g2d.setFont(new Font("TimesRoman", Font.PLAIN, fontSize));
g2d.drawString("test", posx, posy, etc.)
If you want simply to draw to a blank image and then save it, just create a BufferedImage using the default constructor. Then, to save the image :
File output = new File("test.png");
ImageIO.write(image, "png", output);
If you want to know more about this, here's a link to Oracle's Java2D tutorials : https://docs.oracle.com/javase/tutorial/2d/images/drawonimage.html
(from where these examples are).
This tool I wrote in Visual Basic 2010 should add an author text to images. The user is able to set the font opacity and position. To make things easier I wanted some position presets as one can see in the bottom right corner. The calculation I am using is (bottom right in this case:
Dim textSize As Size = TextRenderer.MeasureText(tagString + curText, curFont)
tmpPos = New Point(srcImg.Width - textSize.Width - 10, srcImg.Height - textSize.Height - 10)
As you can see this works perfectly for this example picture. Where as on some the text just clips out.
First One: 1024x768 | Detected Font Size: 680x72
Second One: 1688x1125 | Detected Font Size: 680x72
I suspect this has something to do with the aspect ratio of the images but I do not know how to fix it.
The text is drawn like that:
brush = New SolidBrush(color.FromArgb(alpha, color))
gr = Graphics.FromImage(editImg)
gr.DrawString(tagString + text, font, brush, pos)
HauptBild.Image = editImg
I found this http://www.codeproject.com/Articles/20923/Mouse-Position-over-Image-in-a-PictureBox and it answered my questions.
is this problem only occuring in your preview or also in the converted File? Please post the Code how you save the New Image. I think you have Set a sizemode in your picturebox which is the Problem. Try it without the sizemode.
Will be better to see more your code, but, as i understand by TextRenderer class it is System.Windows.Forms. Just do not use Graphics, created from control (i suppose it is pictureBox with sizemode:Zoom), use Graphics, created from your image instead.
Here is code (sorry, C#), which loads image from file, draws text starting from the same coordinate and places on puctureBox1. Text always starts from Point(100,100).
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Image files|*.jpeg;*.png;*.jpg;*.gif;*.bmp";
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
Bitmap orig=(Bitmap)Bitmap.FromFile(openFileDialog1.FileName);
//workaround for images with color table, see remarks here https://msdn.microsoft.com/en-us/library/system.drawing.graphics.fromimage(v=vs.110).aspx
Bitmap bmp=orig.Clone(new Rectangle(0, 0, orig.Width, orig.Height), System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
Graphics g = Graphics.FromImage(bmp);
g.DrawString("hello", new Font(this.Font.FontFamily,30,FontStyle.Bold ) , new System.Drawing.SolidBrush(System.Drawing.Color.Yellow ), new Point(100, 100));
this.pictureBox1.Image = bmp;
orig.Dispose();
}
catch (Exception ex)
{
MessageBox.Show("Something goes wrong: " + ex.Message+ "\\n"+ ex.StackTrace );
}
}
I am using GDI+ to draw the initial image on PictureBox - which renders a clean image. I am trying to then capture that drawing and draw it on a PDF using PDFSharp which works, but comes out blurry. I am sure it has something to do with the fact I have changed the destination Rectangle's size. What do i need to do to clean it up?
Code:
Dim bmp As New Bitmap(pb.Width, pb.Height)
Dim pdf As New PdfDocument
Dim page As PdfPage = pdf.AddPage
Dim g As XGraphics = XGraphics.FromPdfPage(page)
pb.DrawToBitmap(bmp, New Rectangle(pb.ClientRectangle.X, pb.ClientRectangle.Y, pb.Width, pb.Height + 20))
g.SmoothingMode = XSmoothingMode.AntiAlias
g.DrawImage(bmp, New XRect(New RectangleF(20, 0, 600, 800)))
pdf.Save(_path)
It's the anti-aliasing that makes images blurry.
AFAIK Adobe Reader draws images with anti-aliasing when used with PDFsharp.
With PDFsharp create an XImage from your BMP and then set
image.Interpolate = false;
for that XImage. This will give a hint to Adobe Reader that anti-aliasing is not wanted for that image.
With respect to screen shots, anti-aliasing is useful when scaling down (e.g. when taking a 400x300 bitmap from an 800x600 screen), but not when scaling up (like Adobe Reader will do with images embedded in PDF files).
See also:
http://forum.pdfsharp.net/viewtopic.php?p=5370#p5370
If you scale an image up, it will come out blurred. There is no other way since there are no additional information in the image and it will just be interpolated in some way. There is no "Zoom in and ENHANCE"-button. :-)
What I did in one of my programs where I wanted to save a controls current look to a file, was to first scale the control to the desired size, then draw it to the bitmap, then resize it down again.
If this works depends on the content of the control of course, wether it's scalable or not and so on.
e.g.
In the example below I have a Chart control that I work with in my export dialog called workingChart.
The steps that are used are:
Save old size
Resize chart to the desired size
Draw control to bitmap
Resize chart back to the old size
This works well and the image comes out crisp, since you do not resize the image itself.
Private Function GetChartScaledImage(wantsize As Size) As Bitmap
Dim oldsize As Size = workingChart.Size
Dim bmp As New Bitmap(wantsize.Width, wantsize.Height)
workingChart.Size = wantsize
workingChart.DrawToBitmap(bmp, New Rectangle(0, 0, wantsize.Width, wantsize.Height))
workingChart.Size = oldsize
Return bmp
End Function
I am creating program with multileyered picturebox, the image of picturebox is update dynamically from bitmap in memory, and i want to clear the selected part on bitmap to transparent color so i can see image of picturebox behind it.
Here is my code
Dim gBmp As Graphics = Graphics.FromImage(GraphLayer(LayerArray))
Dim TileSrcCrop As New Rectangle(nVal(xTile), nVal(yTile), TileSize, TileSize)
Dim TileDrawSize As New Rectangle(nVal(H), nVal(V), TileSize, TileSize)
gBmp.DrawImage(GraphImage(LayerArray), TileDrawSize, TileSrcCrop, GraphicsUnit.Pixel)
PicMap(LayerArray).Image = GraphLayer(LayerArray)
Thanks
What I'm about to say may only be for Windows icons, but IIRC, the top left pixel must be assigned the color that you want to designate as the color for transparency. You'll usually see MS use Magenta (255, 0, 255). This is called a transparency mask. Then, anywhere you want the color to be transparent, you use the color you placed in the top left pixel.
HTH -- and let me know if it's only for icons, but I think it's for Windows bitmap files, too.