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.)
Related
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
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.
My program is working with fax documents stored as separate bitmaps
I wonder if there is a way to detect automatically page orientation (vertical or horizontal) to show image preview for user in right order (meant rotate if neccesary)
Any advices much appreciated!
EDIT: Clarification:
When Faxmachine receives multi-page document it saves each page as separate TIFF file.
My app has built-in viewer displaying those files. All files are scaled to A4 format and saved in TIFF (so there is no change to detect orientation by height/width parameters)
My viewer displays images in portrait mode by default
What I'd like to do is automagically detect situation when org document was printed in landscape mode (eg wide Excel tables) then I'd like to show rotated preview for end user to speed up preview process
Obviously there are 4 possible fax orientation portrait / landscape x 2 kinds of rotations.
I'm even interested simplified solution detecting when org doc was landscape or portrait (I've noticed most of landscape docs needs to be rotated clockwise)
EDIT2: Idea
I think it might be some idea:
If I could draw horizontal and vertical lines and check if line doesn't cut any (black) point. Then we can compare what are more type of lines (horizontal or vertical) and his decides about page orientation.
What do you think ?
You could perform a Fast Fourier Transform (FFT) to convert your spatial image to a frequency/angle representation. Then find the angle with the most prominent frequency. It sounds complicated but it's not that hard, it's pretty efficient, and in effect it tests every possible angle at once, instead of being a hard-coded hack that only works for specific angles. Search for a sample implementation with search terms like Numerical Recipes and FFT.
You'd need OCR for that. Rolling your own OCR would be a bit difficult, but there might be library or something out there worth looking into? Also, even with good OCR, it's not a 100% reliable solution.
I wonder if there are some properties of text you could use to help you do this.
For instance based on a quick glance, there are far more vertical lines in text (l,j,k,m,n etc) than horizontal ones so maybe you could start with this.
But even detecting these isn't straightforward, you'd need to use some sort of filter like a Sobel or Prewitt. They both have horizontal and vertical versions, see here for more info.
Of course the vertical/horizontal lines of an excel spreadsheet would be the strongest edges so you'd have to ignore these and look only at the text.
Alternative: Can you not just give the user an easy way to rotate the images, like the arrows in Windows Picture viewer or just show 4 thumbnail previews they can click on. You might need to cache the 4 versions (if you are rotating) so it's quick, but only if speed turns out to be an issue?
Here's a paper entitled "Combined Script and Page Orientation Estimation using
the Tesseract OCR engine" [pdf]
I haven't been able to find an implementation of their work, but the approach looks good to me:
The basic idea behind the proposed approach is simple.
A shape classifier is trained on characters (classes) from all the scripts of interest. At run-time, the classifier is run independently on each connected component (CC) in the image and the process is repeated after rotating each CC into three other candidate orientations (90°, 180° and 270° from the input orientation).
The algorithm keeps track of the estimated number of characters in each script for a given orientation, and the accumulated classifier confidence score across all candidate orientations. The estimate of page orientation is chosen as the one with the highest cumulative confidence score, and the estimate of script is chosen as the one with the highest number of characters in that script for the best orientation estimate.
I'm trying to develop an image focusing algorithm for some test automation work. I've chosen to use AForge.net, since it seems like a nice mature .net friendly system.
Unfortunately, I can't seem to find information on building autofocus algorithms from scratch, so I've given it my best try:
take image. apply sobel edge detection filter, which generates a greyscale edge outline. generate a histogram and save the standard dev. move camera one step closer to subject and take another picture. if the standard dev is smaller than previous one, we're getting more in focus. otherwise, we've past the optimal distance to be taking pictures.
is there a better way?
update: HUGE flaw in this, by the way. as I get past the optimal focus point, my "image in focus" value continues growing. you'd expect a parabolic-ish function looking at distance/focus-value, but in reality you get something that's more logarithmic
update 2: okay, so I went back to this and the current method we're exploring is given a few known edges (okay, so I know exactly what the objects in the picture are), I do a manual pixel intensity comparison. as the resulting graph gets steeper, I get more in focus. I'll post code once the core algorithm gets ported from matlab into c# (yeah, matlab.. :S)
update 3: yay final update. came back to this again. the final code looks like this:
step 1: get image from the list of images (I took a hundred photos through the focused point)
step 2: find an edge for the object I'm focusing (In my case its a rectangular object that's always in the same place, so I crop a HIGH and NARROW rectangle of one edge)
step 3: get the HorizontalIntensityStatistics (Aforge.net class) for that cropped image.
step 4: get the Histogram (gray, in my case)
step 5: find the derivative of the values of the histogram
step 6: when your slope is the largest, is when you're in the most focused point.
You can have a look at the technique used in the NASA Curiosity Mars Rover.
The technique is described in this article
EDGETT, Kenneth S., et al. Curiosity’s Mars Hand Lens Imager (MAHLI) Investigation. Space science reviews, 2012, 170.1-4: 259-317.
which is available as a PDF here.
Quoting from the article:
7.2.2 Autofocus
Autofocus is anticipated to be the primary method by which MAHLI is
focused on Mars. The autofocus command instructs the camera to move to
a specified starting motor count position and collect an image, move a
specified number of steps and collect another image, and keep doing so
until reaching a commanded total number of images, each separated by a
specified motor count increment. Each of these images is JPEG
compressed (Joint Photographic Experts Group; see CCITT (1993)) with
the same compression quality factor applied. The file size of each
compressed image is a measure of scene detail, which is in turn a
function of focus (an in-focus image shows more detail than a blurry,
out of focus view of the same scene). As illustrated in Fig. 23, the
camera determines the relationship between JPEG file size and motor
count and fits a parabola to the three neighboring maximum file sizes.
The vertex of the parabola provides an estimate of the best focus
motor count position. Having made this determination, MAHLI moves the
lens focus group to the best motor position and acquires an image;
this image is stored, the earlier images used to determine the
autofocus position are not saved.
Autofocus can be performed over the
entire MAHLI field of view, or it can be performed on a sub-frame that
corresponds to the portion of the scene that includes the object(s) to
be studied. Depending on the nature of the subject and knowledge of
the uncertainties in robotic arm positioning of MAHLI, users might
elect to acquire a centered autofocus sub-frame or they might select
an off-center autofocus sub-frame if positioning knowledge is
sufficient to determine where the sub-frame should be located. Use of
sub-frames to perform autofocus is highly recommended because this
usually results in the subject being in better focus than is the case
when autofocus is applied to the full CCD; further, the resulting
motor count position from autofocus using a sub-frame usually results
in a more accurate determination of working distance from pixel scale.
The following is Figure 23:
This idea was suggested also in this answer: https://stackoverflow.com/a/2173259/15485
It may be a bit simplistic for your needs, but I've had good results with a simple algorithm that looks at the difference to neighbouring pixels. The sum of the difference of pixels 2-away seems to be a reasonable measure of image contrast. I couldn't find the original paper by Brenner in the 70's but it is mentioned in http://www2.die.upm.es/im/papers/Autofocus.pdf
Another issue is when the image is extremely out of focus, there is very little focus information, so it's hard to tell which way is 'moving closer' or to avoid a local maximum.
I haven't built one myself, but my first thought would be to do a 2D DFT on a portion of the image. When out of focus, high frequencies will disappear automatically.
For a lazy prototype, You could try to compress a region of the image with JPEG (high quality), and look at the output stream size. A big file means a lot of detail, which in turn implies the image is in focus. Beware that the camera should not be too noisy, and that you can't compare file sizes across different scenes of course.
This might be useful. It's how camera's AF system actually works - Passive Autofocus
Contrast measurement
Contrast measurement is achieved by
measuring contrast within a sensor
field, through the lens. The intensity
difference between adjacent pixels of
the sensor naturally increases with
correct image focus. The optical
system can thereby be adjusted until
the maximum contrast is detected. In
this method, AF does not involve
actual distance measurement at all and
is generally slower than phase
detection systems, especially when
operating under dim light. As it does
not use a separate sensor, however,
contrast-detect autofocus can be more
flexible (as it is implemented in
software) and potentially more
accurate. This is a common method in
video cameras and consumer-level
digital cameras that lack shutters and
reflex mirrors. Some DSLRs (including
Olympus E-420, Panasonic L10, Nikon
D90, Nikon D5000, Nikon D300 in Tripod
Mode, Canon EOS 5D Mark II, Canon EOS
50D) use this method when focusing in
their live-view modes. A new
interchangeable-lens system, Micro
Four Thirds, exclusively uses contrast
measurement autofocus, and is said to
offer performance comparable to phase
detect systems.
While the sobel is a decent choice, I would probably choose to do an edge magnitude calculation on the projections in x and y directions over several small representative regions. Another .NET friendly choices based on OpenCV is # http://www.emgu.com/wiki/index.php/Main_Page.
I wonder if the standard deviation is the best choice: If the image gets sharper, the sobel filter image will contain brighter pixels at the edges, but at the same time fewer bright pixels, because the edges are getting thinner. Maybe you could try using an average of the 1% highest pixel values in the sobel image?
Another flavor for focus metric might be:
Grab several images and average them ( noise reduction).
Then FFT the averaged image and use the high to low frequencies energy ratio.
The higher this ration the better focus. A Matlab demo is available (excluding the averaging stage) within the demos of the toolbox :)
I have some code in .Net to draw some text content using GDI+. I used GraphicsUnit.Point to size the text. It's working wonderfully on-screen, and even if Print it.
I've been asked to make a system that generates a PDF, and I got ComponentOne's PDF control. It has got similar interface to GDI+.
The problem is: Font sizes are not working. If I use GraphicsUnit.Point, the text is much smaller, and I am getting empty space below the text. When I use GraphicsUnit.World, the text is still small, but there's no extra empty space below the text.
I want to understand how to convert GraphicsUnit.World to GraphicsUnit.Point.
All help will be appreciated.
Thanks
After some Googeling and from what I know from personal experience with GDI+ and String drawing it comes down to DPI (Dots per Inch). Basically the different devices (and as far as GDI+ is concerned, PDF is probably a device) have different DPI values. Displays usually have something like 70 DPI. Printers use 72. I don't know what PDFs use, but it might be 100 (as this is a common value for device independence and would explain the smaller text).
Now, Points are defined as being 72 DPI. This is always true. What GDI+ should do, when drawing to a PDF with a different DPI is, to transform the string drawing accordingly. But this does not always work, especially with text.
The GraphicsUnit.World should (according to some googeling) be device independent and should look the same on all devices.
You're right, GraphicsUnit.World looks the same on print, and also on screen. My final solution was to use GraphicsUnit.World as the unit of measure, and shun points. I still don't know the conversion ratio, but I approximated the value till the look was okay.
For my purpose this was enough.