I created an extended RichTextBox with better image displaying support. For short: I parse text-based image placeholders from the RTF-input, replace them by an empty paragraph with a propriate spacing (image height) and draw the images in the paint event above the text (inside the spaces).
The problem now is that the spacing seems to be wrong. I calculated the twips with the following formula:
size.Width = (int)((1440 * size.Width) / graphics.DpiX);
size.Height = (int)((1440 * size.Height) / graphics.DpiY);
Where graphics is from my RichTextBox and size is the image size. As the DPI value is 96, it is basically twips = 15 * pixels.
I tried the RTF control words \sbN and \saN with my calculated twips-value (I controlled it with the debugger, the value is as expected). I also used interop with PFM_SPACEBEFORE and PFM_SPACEAFTER.
Both ways give the same result. The problem is that the real space inside the RichTextBox is too big. If I multiply the calculated twips value with 0.75 it fits. But I really don't get why this happens.
My first thought was the factor 72 / 96 (PPI / DPI) which is 0.75. But this makes no sense for me.
The additional space increases proportional to the image height. So the space is barely noteable for small icons (e.g. 24 pixels height). But for larger images (e.g. 320 pixels height) the additional space is huge.
Some ideas? Is this a bug in the RichTextBox control?
To clarify: I used System.Windows.Forms.RichTextBox as a base class.
Ok I found the error by myself. I had to use the DPI values of the image instead of the DPI values of the control. The image DPI values were 120 so the factor was 0.8 (not 0.75). Now it fits. I leave the question here in case someone has the same problem.
Related
If I create picturebox element on a form, the properties panel allows me to set the width/height to a value representing pixels.
However in code it seems a different unit size is used for measurement.
Example; i put the width at 128.
Both in the editor and in runtime the form will show a picturebox of 128 pixel width.
Now, If i try to read picturebox.width value in code it gives back 85.
If I try to change the width to 128 in code, it gives me an actual bigger box then 128 pixels.
What am I missing here?
I need to know whether there is any advantages or disadvantages on using 2d graphics in wpf over 2d images or not?
I mean if I'm going to display an ellipse in a wpf window which one is more useful and why? To create an Ellipse object or to create an Image control and then load an pre-designed ellipse image into it?
Does using 2D graphics have any advantages in the sense that they consume less memory or increase performance or anything like that?
Thanks in advance.
An Image is not realy good scalable.
An vector Graphics is.
On a high dpi display your Image with Width = 300 (Units not pixels) and Height = 300 (units) is on a Display with 96 dpi not bigger than a Display with 144dpi. But the Image on the 144 dpi display needs more Pixels for the same size.
1 Unit is 1/96 inch.
So it is better to have a scalable "image" than a fixed one.
Its one of the features of wpf that winform don't have! and the reason why you should not use Pixels as a Size / Width / Height / Position / etc.
Excursus:
In winform it is hard to programm a scalable programm. on high dpi monitors the font, buttons etc. looks very small. there was no option to solve this problem.
so windows programmed an algorithm that creates a bitmap of the programm and scales this up.
So: the progamms width and height is the same as before, but the user sees a much bigger one (the Bitmap). The user input is then recalculated on the real sized application; Everything is working fine - and looking fine.
Hope that helps and is correct.
For example, C # says that the selected image contains 96 ppi, while that same image in Photoshop contains 72 ppi.
Why is there a difference?
I’m inclined to trust Photoshop in this case, and how to test image resolution if C# returns false results?
We need to build some sort of validator control that rejects all images with ppi != 300.
Control should support the following formats: jpg, jpeg, gif, png, bmp.
Code is listed below:
Image i = Image.FromFile(FileName);
Console.Write(i.VerticalResolution);
Console.Write(i.HorizontalResolution);
DPI means dots (pixels) per inch. The physical size in inches is subjective, based on the current monitor's size and resolution. Unless you're relying on metadata (which gif and bmp don't contain) you cannot reliably calculate this.
Photoshop simply has a prescribed value for DPI, which it uses when translating images for print. This value is stored in the PSD file and may be copied to JPEG metadata, but if you save the image in a format without DPI metadata, the information is not stored.
Update:
The reason your code gets a different value is that C# fetches its VerticalResolution and HorizontalResolution values from the current DPI setting on the computer. Photoshop's DPI is for use with print, so it knows the physical dimensions if you want to send your image to a printer. It has a default value of 72dpi, but you can change this. The value has no meaning on a screen, though, since screens deal in pixels only.
DPI means dots per inch. A bitmap image does not have an inherent DPI, it merely has a size which is the number of pixels in the horizontal and the number of pixels in the vertical (width and height). An image only gains a resolution (in DPI) when you say how many pixels you want to squeeze into each inch.
So if I have an image that is 100 pixels wide and 100 pixels high (100px × 100px), it will be 100 DPI if I print it (or convert it into a format that dictates the print size) such that it fits exactly in a one square inch (1" × 1"). It will be 50 DPI if I print it to fit in a square that is two inches by two inches, &c.
I have two images:
Name Type Width Height HRes VRes
img01 GIF 256 256 384 96
img02 TIFF 1728 1147 200 100
Windows internal viewer shows them using different patterns:
img01 is displayed as 256x256 image (square)
img02 is displayed as a vertical image (despite of width>height) and image format is correct
After seen img02 behaviour I thought that displayed size is given by:
Display_Width = max(HRes,VRes) * Width / HRes
Display_Height = max(HRes,VRes) * Height / VRes
But that's not good for img01, which is displayed as 256x256!!
If I use Image class to load those images, resolution is not taken in account, so img02 is shown horizontally and distorced respect correct format.
If Windows internal viewer shows them correctly, I think there should be some property to understand if resolution should be considered or not.
With Image class I have Flags and PropertyItems properties, but I really don't understand if they are the ones I have to look at.
Can you teach me the right method to display images (using Image class) without distortion?
Thanks
Aspect ratio in GIF files is very uncommon, since GIF is a format used to store graphics intended to be displayed on computer screens. In fact, GIF87a files do not have an aspect ratio at all, and GIF89a do not store the actual aspect ratio but an approximation.
On the other side, TIFF files for the most part are used by graphic designers, photographers and publishers, so the concept of pixel aspect ratio is core to the format as it allows these files to move between different display mediums.
My guess is that most GIF decoders ignore the aspect ratio from the GIF89a format. I think you should do the same.
I want to know the printing size of a string in inches. i.e. what will be the length (and width) of string "Test String" when printed on a paper. I can get the length in pixels using the Graphics object and MeasureString method. But don't know how to convert pixels into inches on paper.
I checked this SO question but can't find the solution.
The resolution of a digital graphic is its pixel dimensions.
The size of the printed graphic is dependent of the printer settings.
If you print a picture of 300 x 300
pixels at 300dpi on a printer the
picture becomes 1 x 1 inch. ( 300 / 300 )
If you print a picture of 300 x 300
pixels at 10dpi on a printer the
picture becomes 30 x 30 inch. ( 300 / 10 )
If you print a picture of 300 x 300
pixels at 1000dpi on a printer the
picture becomes 0,3 x 0,3 inch. (300 / 1000 )
However, the exact size depends on the accuracy of the printer (paper feeding, servo of the printer head etc.)
An excellent reference is found here: DPI has NOTHING to do with digital image quality!.
The Dpi of the display has NOTHING to do with this
I know this is an old question, but a quazi solution for it. I have tested my solution a few times and it seems to be accurate but not precise. The basis of this code is directly from an MSDN example and this answer on SO, the only thing I am doing differently is changing the units from points to inches.
MSDN Graphics.MeasureString()
private float GetTextWidth(string fontFace, float fontSize, string text)
{
SizeF size = new SizeF();
Font font = new Font(fontFace, fontSize);
//Using a Bitmap object for frame of reference in order to get to a Graphics object
using (Bitmap b = new Bitmap(1, 1))
{
//Graphics object allows string measurement
using (Graphics g = Graphics.FromImage(b))
{
//change the units to inches
g.PageUnit = GraphicsUnit.Inch;
//Perform the measurement
size = g.MeasureString(text, font);
}
}
//Print to console if you want
//Console.WriteLine(size.Width);
return size.Width;
}
I tested this out with the following inputs:
("Arial", 10, "Page 1 of 1") and I got 0.777972 inches
If you read the Remarks of the MSDN link above you will see that there is a little extra space padded onto that figure. You have to be aware that this happens:
The MeasureString method is designed for use with individual strings
and includes a small amount of extra space before and after the string
to allow for overhanging glyphs.
When I measured this on a piece of paper end to end I got about 0.625, that is a difference of 0.152972 which is essentially ~20% padding. I'm guessing it is distributed on either side evenly.
Also be careful with which Fonts you use - for example Helvetica is not a supported font by default, therefore the Font object will default to Arial if it can't find your font.
This is not possible, unless you know both the printer size and display size in hard numbers.
Say you're printing a full screen handout. On a 30 inch monitor, 1 pixel may be 1 unit large on paper. But on a 7 inch netbook, a pixel will be 2 units large on paper - twice the size, even though they are both one pixel on the electronic display.
Simply put, this measurement is not possible unless you are working with something fixed, like an iPhone's display size (which is well known), or your own hardware whose screen size you have exact measurements to.