Resolution of the generated pdf file - c#

I have a problem with the resolution in a PDF file generated on the basis of HTML
I am using HtmlToPdfConverter from Syncfusion together with WebKitConverter
The A4 paper size is set to 595px x 842px
I worked on Windows 7 with an older screen. Everything was fine
When run on a Windows 10 system with a different screen, the paper content is larger than paper. The text is too big, the pictures are too big
The size of the text is also set in pixels.
For sure the difference is in PPI
A code snippet with generator settings:
PdfMargins margins = new PdfMargins();
margins.Left = 50;
margins.Right = 50;
margins.Top = 0;
margins.Bottom = 0;
settings.Margin = margins;
settings.Orientation = PdfPageOrientation.Portrait;
settings.WebKitViewPort = new System.Drawing.Size(595, 0);
settings.PdfPageSize = new SizeF(595, 842);
Is it possible to set in some way that it will always work?

The content size of PDF document may different based on machine/application where the conversion take place. If you need a same output in all the machine/application then please set a fixed viewport size in WebKitViewPort property. WebKit HTML converter internally using system viewport size for converting HTML to PDF. The system viewport size may differs based on the system and application.
Even the fixed WebKitViewPort size does not helps, please provide us the complete code snippet for the conversion, so that it will helpful for us to analyze and assist you further on this.
Please refer below links for more details about WebKit viewport.
UG: https://help.syncfusion.com/file-formats/pdf/convert-html-to-pdf/webkit#viewport
KB: https://www.syncfusion.com/kb/7412/
Note: I work for Syncfusion

Try setting the size in em instead of px for you text sizing. You can set the pictures in percentage. You want to make everything scaled to the paper size.
“Ems” (em): The “em” is a scalable unit that is used in web document
media. An em is equal to the current font-size, for instance, if the
font-size of the document is 12pt, 1em is equal to 12pt. Ems are
scalable in nature, so 2em would equal 24pt, .5em would equal 6pt, etc
Meet the Units
“Ems” (em): The “em” is a scalable unit that is used in web document
media. An em is equal to the current font-size, for instance, if the
font-size of the document is 12pt, 1em is equal to 12pt. Ems are
scalable in nature, so 2em would equal 24pt, .5em would equal 6pt,
etc. Ems are becoming increasingly popular in web documents due to
scalability and their mobile-device-friendly nature.
Pixels (px): Pixels are fixed-size units that are used in screen
media (i.e. to be read on the computer screen). One pixel is equal
to one dot on the computer screen (the smallest division of your
screen’s resolution). Many web designers use pixel units in web
documents in order to produce a pixel-perfect representation of
their site as it is rendered in the browser. One problem with the
pixel unit is that it does not scale upward for visually-impaired
readers or downward to fit mobile devices.
Points (pt): Points are traditionally used in print media (anything
that is to be printed on paper, etc.). One point is equal to 1/72 of
an inch. Points are much like pixels, in that they are fixed-size
units and cannot scale in size.
Percent (%): The percent unit is much like the “em” unit, save for a
few fundamental differences. First and foremost, the current
font-size is equal to 100% (i.e. 12pt = 100%). While using the
percent unit, your text remains fully scalable for mobile devices
and for accessibility.
So, What’s the Difference?
It’s easy to understand the difference between font-size units when you see them in action. Generally, 1em = 12pt = 16px = 100%. When using these font-sizes, let’s see what happens when you increase the base font size (using the body CSS selector) from 100% to 120%
As you can see, both the em and percent units get larger as the base font-size increases, but pixels and points do not. It can be easy to set an absolute size for your text, but it’s much easier on your visitors to use scalable text that can display on any device or any machine. For this reason, the em and percent units are preferred for web document text.
https://kyleschaeffer.com/css-font-size-em-vs-px-vs-pt-vs-percent

Related

How to control Excel's scaling of bitmaps

I have a bitmap image and I want to put it in excel. I used this code I found here:
xlWorkSheet.Shapes.AddPicture("C:\\filesystem\\mb2.bmp",
msoFalse, msoCTrue, 0, 0, 518, 390);
But the resulting image is 1.333 times wider and higher. OK, so I can just multiply the dimensions by 0.75 and I get an image in excel with the desired dimensions.
xlWorkSheet.Shapes.AddPicture("C:\\filesystem\\mb2.bmp",
msoFalse, msoCTrue, 0, 0, (float)(518*0.75), (float)(390*0.75));
But that number 0.75 sitting there hard-coded really bothers me. Especially since I've seen this question in which the op's ratio is 0.76. Knowing that this code needs to run on any number of systems with different displays, I want to know how to get the ratio programmatically.
Somewhat also related to this question which has to do with copy-paste without code.
If you are talking about printing, the display is irrelevant.
The dimensions of the image need to be relative to the paper size. The size values in the AddPicture method are in points and are only loosely related to pixels. Points are units if measure that make sense to your printer. The application translates points to pixels for you so you don't need to worry about that.
You can use the InchesToPoints or CentimetersToPoints methods of the Application object to size your image to paper size.

How to set "Resolution Unit" when regenerating\saving an image

I'm trying to investigate an issue I thinking I'm seeing in an application that generates a TIF image.
To do this I'm trying to regenerating\saving the image myself following this msdn Encoder.Compression example (except I'm using CompressionCCITT4).
The output file has a 'Resolution unit' = 2 but I would like to set that to 1.
Questions:
Any ideas how to do set the 'Resolution unit'?
Any ideas on the effect that would\should have on the image?
Thanks!
Disclaimer: Being a Java guy, I don't know how to set it using the library you describe. So I'll only answer question part 2:
Any ideas on the effect that would\should have on the image?
The quick answer is: None. It only matters when you import the image into a page-setting/layout program, word processor, print it, etc. But a lot of software simply assumes 72dpi in both x/y dimensions regardless.
Here's what the TIFF spec says:
Typically, TIFF pixel- editors do not care about the resolution, but applications (such as page layout programs) do care.
And:
1 = No absolute unit of measurement. Used for images that may have a non-square aspect ratio, but no meaningful absolute dimensions.
The drawback of ResolutionUnit=1 is that different applications will import the image
at different sizes. Even if the decision is arbitrary, it might be better to use dots per
inch or dots per centimeter, and to pick XResolution and YResolution so that the aspect ratio is correct and the maximum dimension of the image is about four inches (the “four” is arbitrary.)

Accurately measuring, rendering, hit testing and printing text in a WinForms application

We need to:
Measure text accurately.
Render text line by line to a screen graphics context in the presence of translation and scaling transforms applied to the graphics context.
Hit testing: allow text to be selected precisely with the mouse or via a displayed caret.
Print the result if needed, and as accurately as possible, with a printer. Note: this is secondary. Screen rendering and hit testing are primary.
Run on Windows XP and higher operating systems.
within a WinForms application that is also rendering graphics and images to the same graphics context.
There are four technologies that we've encountered. We've tried using the first two, and ran into the issues described, over the course of several months.
GDI+
Purportedly resolution-independent text. However according to this question - and other sources - this technology is to be avoided because of quality issues.
MSDN states that calling Graphics.MeasureString along with StringFormat.GenericTypographic and TextRenderingHint.AntiAlias produces accurate string measurement. However, in our experience, and that of others, this is not the case - we do not get accurate string measurements.
Pros: Fast
Cons: inaccurate string measurement.
Result: unusable because of inaccurate string measurement.
GDI via TextRenderer
This was introduced to overcome the limitations of GDI+. However this introduced limitations of its own:
Very slow
Does not work with graphics transforms
Result: unusuable for these reasons
GDI via p/invoke
Calling GetTextExtentExPoint for text measurement and DrawText / DrawTextEx / ExtTextOut for rendering.
We haven't tried this yet.
DirectWrite
This seems promising, since it interoperates with other technologies including GDI/GDI+, so presumably the rest of our graphics rendering wouldn't change. However it is only available for Windows Vista and more recent Windows versions. This is presently a problem since Windows XP still has a significant installed base.
Question
Which of these technologies can be made to work given the requirements?
Note: There's much misinformation about this topic floating around, so please answer this question only if you have expertise in this area.
Also, please don't suggest WPF - that isn't something we're considering using.
Supposedly the MeasureCharacterRanges function is more accurate than MeasureString.
If you have to target both the screen and a printer, then you need to make some decisions about your approach before deciding which rendering engine to use. Here are some possibilities:
Lay out in screen units and do a best-possible approximation for the printer.
Lay out in printer units and do a best-possible approximation for the screen.
Lay out in a theoretical high-resolution space and do a best-possible approximation for both printer and screen.
In all cases, the best-possible approximation might be done by very careful approximations at each step, which can give the highest fidelity for each device at the cost of accuracy in matching, or you could render to bitmap and scale to the device, which gives lower fidelity but a the best-possible approximation to the other space.
I've done hard-core print preview with GDI. It's hard, but do-able for regular layouts. But if you're handling arbitrary transforms, especially rotations other than +/-90 degrees, it's nigh impossible.
It's very easy to make subtle mistakes and believe that the measurements you get back are wrong.
Font hinting makes font scaling non-linear when the stroke widths are on the same order of magnitude as the dpi, so if you get a width w for some text, then the width if you double the size of the font may not be exactly 2*w.
Font substitution is common in many printer drivers. Even if you choose a TrueType or OpenType font you might not get the same font on the printer as you got on the screen.
Non-square pixels are common in some printers. These can mess up even decent rasterizers when you're doing something that's not axis-aligned.
Kerning can be surprising. Don't assume that width('a') + width('b') == width("ab").
Rounding errors are easy to make. Sometimes you have to know the rounding rules used by the underlying rasterizer.
Measuring in the wrong context is too common. Don't try to measure in a screen context and apply a transform to get to printer units. If you need printer units, measure in the printer context.
I'm of the opinion today that if you need just print preview, then you should lay out in printer units to a bitmap that's sized to the page, and scale the bitmap to the screen based on the ratios of the DPIs. That's the easiest thing to do and it gives good results. But it's not clear if a good hardcopy and print-preview is really what you're after.
I had similar requirements and ran into the same problems with text rendering and scaling. Even my attempts with WPF (.NET 3.5) were a nightmare, for many reasons.
I ended up using GDI+ graphics.DrawString, despite being 'deprecated', with a funny trick to get accurate text measurements.
static public RectangleF MeasureInkBox(Graphics graphics, string text, Font font)
{
var bounds = new RectangleF();
using (var textPath = new GraphicsPath())
{
textPath.AddString(
text,
font.FontFamily,
(int)font.Style,
font.Size,
new PointF(0, 0),
StringFormat.GenericTypographic );
bounds = textPath.GetBounds();
}
return bounds;
}
The speed and quality turned out to be satisfying. Also, graphics.DrawString is the recommended way to print text with winforms.
Measuring individual character positions can be tricky due to kerning, but I guess a slightly more complex version of this method could do the job. For example, for "Hello" it would measure "H", then "He", then Hel" and so on. It should not degrade performances significantly, especially if you do it on he fly when receiving a click on the word.

Accuracy with calculations on images scanned with TWAIN

I'm using the TWAIN libraries to scan a greyscale image. I then programmatically adjust each pixel in the scanned image to have different white and black endpoints. So pixels with a colour value of less than the blackpoint are clamped to the blackpoint. And pixels with a colour value of greater than the whitepoint are clamped to the whitepoint. Also, all pixels that are inbetween are extrapolated.
My problem is that I'm losing quality in the calculation because the scanned image I'm doing the calculation on is only 8bits per colour channel.
I either need some way of acquiring the image with a higher number of bits per colour channel, or I need to tell the scanner to do this calculation for me.
I know that the Epson control panel allows you to specify black and white end points and do this calculation, and it looks like it's not having the accuracy issues. So I wonder if it's doing something specific to the Epson hardware. Unfortunately my software needs to use generic printers.
Does anyone know a way around this problem?
Some models of TWAIN scanner - mostly they are flatbeds - can deliver data deeper than 8 bits/channel.
Your code needs to set the transfer mechanism (ICAP_XFERMECH) to memory (TWSX_MEMORY), set the pixel type (ICAP_PIXELTYPE) to TWPT_GRAY, then see if you can set ICAP_BITDEPTH to 16.
If that succeeds, you can then do a memory (AKA buffered) image transfer, and get 16-bit/channel data. I expect you'll find that the data is in the 10-12 upper bits (i.e. the sample range is 0..65535) and the low bits are noise.
You can't use native transfer mode (TWSX_NATIVE) because the native image formats (DIB and PICT) don't support 16-bit/channel data. You might be able to use file transfer mode with a file format that supports 16-bit/channel data, like TIFF or JFIF: You'd just have to experiment with the scanner.
I just did this with an Epson Perfection V100 Photo I have on my desk, I'm sure other Epsons support this, maybe all the Perfection series.
See: Twister Report archive
And yes, the reason this works well with 8-bit scans when you do contrast adjustments in the scanner's UI is that the scanner is adjusting the contrast by tweaking the gain in an amplifier - so working in the analog domain. (Effectively, infinite bits/channel ;-)
You could exploit that circuitry: Most flatbeds will let you set ICAP_SHADOW, ICAP_HIGHLIGHT and ICAP_CONTRAST - which has the same effect as setting the black level, white level and contrast in the scanner UI. Then you'd be adjusting the analog signal, and you'll get dense 8-bit histograms.

C# WPF resolution independancy?

I am developing a map control in WPF with C#. I am using a canvas control e.g. 400 x 200 which is assigned a map area of e.g. 2,000m x 1,000m.
The scale of the map would be: canvas_size_in_meters / real_size_in_meters.
I want to find the canvas_size_in_meters.
The canvas.ActualWidth gives the Width in DIU's (Device Independant Units). So, 400 DIU's is 400/96 = 4,17 inches, PROVIDED that the physical resolution of my monitor is 96 dpi.
However, using a ruler, I found that the physical resolution of my monitor is 87 dpi. (There are only few monitors that ACTUALLY have 96 physical dpi)
That DPI difference (10%) translates to a +10% difference in the actual map control width on screen.
How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?
How do I measure the size of a WPF control in inches EXACTLY and regardless of screen resolution and DPI setting ?
This isn't actually possible, because for it to work, WPF would have to know the resolution (in terms of DPI) of your monitor. Sounds nice in theory, but in practice windows doesn't know this information. This is why windows itself always assumes 96dpi blindly instead of being smarter about it.
Even if there were some way to manually tell it, or if your particular monitor has a custom driver that does pass the correct information to windows, this isn't going to work on anyone else's computer, so windows doesn't pass this information on to any applications.
The best you can do is draw a scale like google maps does. You know that 1 pixel == 1 mile, so you can draw a 50 pixel line on your map, with a label saying "this line equals 50 miles"
There is way to compute current pixel size in mm or inches. As mentioned in the earlier posts, it is not a fixed value and would vary depending on the current resolution and monitor size.
First get the current resolution. Assume it is 1280x1024
Now get the monitor width in mm using GetDeviceCaps function. Its a standard windows library function.
int widthmm = GetDeviceCaps(deviceContext, HORZSIZE);
My monitor width is 362mm
So pixel size = 362/1280 = 0.282 mm
The accuracy of this method depends on the assumption that the display area covers the width of the monitor exactly.
So to answer the original question, the canvas size of 400 x 200 pixels would be
(400 * 0.282/1000) x (200 * 0.282/1000) in meters when shown on my monitor.
Thank you for you prompt reply.
I totally agree, but I didn't want to believe it in the first place. You see, there has to be an approximate calculation of the scale of the map if the map is used to display different layers of map data (scale dependant).
Most applications use a slider control with e.g. 10 discrete map levels to set the "scale".
Having an absolute scale is not crucial for the application, it would be nice to display an indicative scale, like 1:15,000.
An absolute scale would require for an extra variable monitorPhysicalDPI (initially set to 96) that if the uses chooses to change would give slightly better scaling (again it's not crucial). The size of the map control would be:
map.ActualWidth * (96/monitorPhysicalDPI) * inchesPerDIU, inchesPerDIU is 1/96
Again these are cosmetics.. Wouldn't it be nice if Windows knew the ACTUAL control's dimensions? (user would have to give information about the screen dimensions on OS setup, or simply installing the monitor INF file)

Categories

Resources