Get resolution of bitmap from file vb .net - vb.net

I have a filename that leads to a picture. It is not an embedded resource. My bitmap object always tells me the resolution is 96x96 no matter what, how can I get the actual resolution. Thanks

96 sounds pretty accurate to me. I think you're confusing pixel dimension with resolution.
Resolution is the number of dots per inch* (DPI), and 96 is a common number for graphics targeted at monitor display.
As mentioned, the Height and Width properties are probably what you're looking for.
*Note: technically, I should have said PPI, as dots and pixels aren't necessarily interchangeable.

The methods you are looking for are those :
Dim bmp as Bitmap = new Bitmap(IMAGE_NAME_LOCATION)
bmp.HorizontalResolution ' --> Horizontal PPI (points per inch)
bmp.VerticalResolution ' --> Vertical PPI
bmp.SetResolution ' --> Define both Horizontal and Vertical PPI

try this (its in C#):
Bitmap b = new Bitmap(IMAGE_NAME_LOCATION);
Size s = b.Size;
s.Height;
s.Width;
Height & width are in pixels. The Height & width are the original pic's size.

If you're loading a file using Bitmap.FromFile("C:\whatever.jpg"), and the resulting Bitmap has a .Width of 96 and a .Height of 96, then that is the actual resolution of that image.
If what you're doing is loading a file into a PictureBox control by setting its Image property in the designer (and browsing for the file), then it may be that your PictureBox just happens to be 96x96 and the SizeMode is set to Stretch, which would make any file you load appear to be 96x96.

It's simple:
Bitmaps don't contain resolution information. They are only an ordered collection of pixels. They're device-independent. You can show the same bitmap at different resolutions (pixels per inch) on two different devices.
The fact that your bitmap object has a resolution property is misleading.

Related

Converting from canvas to PDF with default at 72 dpi causes incorrect page size

I am creating a canvas with predefined dimensions (2505px width, 3542px height) which are the dimensions for an A4 paper in 300 DPI resolution.
I am converting the canvas to pdf using createPDFStream (https://github.com/Automattic/node-canvas#canvascreatepdfstream). The outputted PDF is good but I notice that the Page Size is 34,79 x 49,19 inches (see image below), which is much larger than a regular A4 paper, which causes some problems further down the line.
I notice that this is because that createPDFStream is assuming that the PDF should be in 72dpi, since 2505px / 72dpi = 34,79 inches & 3542px / 72 dpi = 49,19 inches. My question is if there is a way to specify to createPDFStream that the PDF is supposed to be in 300dpi so that we get the correct Page Size. Alternatively, if there is a library to use to correct the Page Size or DPI settings without compromising the 300 DPI image quality.
I tried digging deeply through the node-canvas for a solution, but I could neither find a way to correct the DPI nor find the place where the 72 DPI assumption is set.

Weird VB.net bitmap-to-picturebox scaling

As part of a larger tool I'm working displaying pieces of a bitmap in a picturebox. In my current test case, I want to take a 200x200 section of the bitmap and display it in a 200x200 picturebox (clientsize area). The code runs, but I find I'm actually getting 600x600 pixels from the bitmap in the picturebox. This is all running on a 4K monitor, and I suspect some dpi-based scaling is the culprit. I will want to use that scaling to allow zoom, but I can't see why it's happening at all right now.
Here's the code - the src_rect and dest_rect are identical, both 200x200, and this variant of DrawImage shouldn't be scaling on its own:
Public Overrides Sub Draw_Data(Pbox As PictureBox, Src_Rect As Rectangle, Dst_Rect As Rectangle)
''Pbox is the destination picturbox:
Dim bm As New Bitmap(Pbox.ClientSize.Width, Pbox.ClientSize.Height)
Dim gr As Graphics = Graphics.FromImage(bm) 'So GR relates to drawing destination.
gr.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
gr.SmoothingMode = Drawing2D.SmoothingMode.None
gr.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
'' Bitmap is the underlying data, a subset of which should be shown:
gr.DrawImage(Bitmap, Dst_Rect, Src_Rect, GraphicsUnit.Pixel)
Pbox.Image = bm
End Sub
I've played with the various gr.* settings, as well as the picturebox properties, trying pretty much anything reasonable, but I always get the same result. If it's an issue of bitmap "resolution", that's odd because the originating bitmap is (at least to me, conceptually) just an array of pixels. It would seem that a mapping of a 200x200 subset of that to a 200x200 bitmap used in the picturebox would be one-to-one. Does anyone see what I might be missing? If there's some scaling I have to apply, I can certainly do it, but I'd have to have some way of at least measuring the kind of weird scaling that's going on before I can compensate for it.

VBA Userform: Text of same font size changes size based on Top property

I have a userform. In multiple cases across several different controls, I have observed the objects with the same Width, Height, Font, and Font Size display different font sizes depending on where they are placed on my userform.
. . . .
Above is an example of this. The two textbox's are both 26H and 48W, with a Left of 90. Both have font Tahoma Regular size 18. The only difference between them is their Top property. And yet visually, the upper one has much wider text than the lower one. The picture on the right has added dots to prove this is not an optical illusion. The upper one can only fit one dot between the letter and the edge. The lower one can fit at least two dots between the letter and the edge.
Can anyone explain why this is happening? What is happening? Or how I could stop it from happening?
Why its happening?
A normal windows graphical application renders in 96dpi/ppi.
However, excel’s rendering system is in 72dpi/ppi,so, when you specify 26 as the height, excel will first convert 72 to 96 dpi.
26 x 96 / 72 = 34.6667
Which means your control height is 34.667 pixels.
This will create artefacts in the rendering of your control.
How can you stop it?
Make sure that the final position of your control and its height has a final pixel position in the form to be a whole number.
You can do this by multiplying by your screen dpi and divide by excel dpi(72)
In your case you can apply a height of 25.5 which will render it correctly.
I hope I solved your answer!!
As Krishna Soni says in this thread, you should use a height of 25.5 for all the reasons he present.
This is equivalent to using controls with a height that is a multiple of 3. Since the rounding of 25.5 is 30, we can take 3 as a multiple of the Top, Height, and Width properties and avoid the text resizing issues.
Seen on Weird change of font size when changing Top proprierty by 1

how can a 512x512 bmp image have 1MB of size

my code to save bmp format:
ImgResult.Save(dlgSavePicture.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
I have tried the code and the output is a 512x512 bmp image with 1 megabyte size
if i use ms paint to create a 515x512 bmp image, the size is 768kb
i have tried to open the image and resave as bmp and the size still 1MB
can a 512x512 bmp image size upto 1mb in 512x512? or there are something wrong with my code?
BMP is a very simple image file format. Just a little header that describes the image (size, pixel format, resolution, color table), followed by a blob of pixel data. Technically it can be compressed with RLE but encoders don't bother anymore. The pixel data depends on the pixel format, ancient ones are 1bpp, 4bpp and 8bpp, they require a color table. 16bpp can happen, unusual, normal ones are 24bpp (RGB) and 32bpp (ARGB). In other words, 3 or 4 bytes per pixel.
So yes, 512 x 512 x 4 ~= 1 megabyte. MSPaint is pretty explicit about the pixel format it uses. It is a very simple painting program without support for alpha blending effects. So uses 24bpp (no alpha), 512 x 512 x 3 ~= 786 kilobytes. You could use Paint.NET to create 32bpp BMPs.
Which one you get in your own program depends on how you created the Bitmap object. The simple version uses the same pixel format as the video adapter. On all modern machines that's 32bpp. 16bpp can happen, it is very unusual. If you want another format then you have to use the Bitmap constructor that takes a PixelFormat argument.
There's otherwise a pretty good reason to do this, the default pixel format is not usually the most optimal one. The best one by a factor of 10 is the format that matches the pixel format of the video adapter exactly. Choice is between 32bppArgb and 32bppPArgb. The P means "pre-multiplied", the alpha value is applied to the RGB values up front. Argb is most efficient if you do a lot of drawing into the bitmap yourself with Graphics.FromImage(). PArgb is most efficient for painting, the pixel data can be blitted to the video frame buffer directly without having to be converted. Ten times faster. You usually care about painting speed, the most visible artifact of a program.
If you care about image file size then there is no better choice than PNG. It compresses the pixel data with LZW compression, typical compression rates are 50% or better. JPEG is a decent choice as well, much higher compression rates, but it is lossy. It achieves high rates by throwing away image details. Suitable for photos, in general images without text or line art, that don't otherwise have to be compressed multiple times.
i have tried this code
Public Function ConvertTo24bpp(img As Image) As Bitmap
Dim bmp = New Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
Using gr = Graphics.FromImage(bmp)
gr.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height))
End Using
Return bmp
End Function
ImgResult = New Bitmap(Original)
For j = 0 To Original.Height - 1
For i = 0 To Original.Width - 1
ImgResult.SetPixel(i, j, Color.FromArgb(resultArray2(j, i, 0), originalArray(j, i, 1), resultArray2(j, i, 2)))
Next
Next
Dim clone As Bitmap
clone = ConvertTo24bpp(ImgResult)
clone.Save(dlgSavePicture.FileName)
the output is 24bit 512x512 bmp image but it size is ~640 KB not ~678 KB
i think the output is png format with bmp extension
is my code gone wrong?

Comparing two images - Detect egg in a nest

I have a webcam directly over a chicken nest. This camera takes images and uploads them to a folder on a server. I'd like to detect if an egg has been laid from this image.
I'm thinking the best method would be to compare the contrast as the egg will be much more reflective than the straw nest. (The camera has Infrared so the image is partly grey scale)
I'd like to do this in .NET if possible.
Try to resize your image to a smaller size, maybe 10 x 10 pixel. This averages out any small disturbing details.
Const N As Integer = 10
Dim newImage As New Bitmap(N, N)
Dim fromCamera As Image = Nothing ' Get image from camera here
Using gr As Graphics = Graphics.FromImage(newImage)
gr.SmoothingMode = SmoothingMode.HighSpeed
gr.InterpolationMode = InterpolationMode.Bilinear
gr.PixelOffsetMode = PixelOffsetMode.HighSpeed
gr.DrawImage(fromCamera, New Rectangle(0, 0, N, N))
End Using
Note: you do not need a high quality, but you need a good averaging. Maybe you will have to test different quality settings.
Since now, a pixel covers a large area of your original image, a bright pixel is very likely part of an egg. It might also be a good idea to compare the brightness of the brightest pixel to the average image brightness, since that would reduce problems due to global illumination changes.
EDIT (in response to comment):
Your code is well structured and makes sense. Here some thoughts:
Calculate the gray value from the color value with:
Dim grayValue = c.R * 0.3 + c.G * 0.59 + c.B * 0.11
... instead of comparing the three color components separately. The different weights are due to the fact, that we perceive green stronger than red and red stronger than blue. Again, we do not want a beautiful thumbnail we want a good contrast. Therefore, you might want to do some experiments here as well. May be it is sufficient to use only the red component. Dependent on lighting conditions one color component might yield a better contrast than others. I would recommend, to make the gray conversion part of the thumbnail creation and to write the thumbnails to a file or to the screen. This would allow you to play with the different settings (size of the thumbnail, resizing parameters, color to gray conversion, etc.) and to compare the (intermediate) results visually. Creating a bitmap (bmp) with the (end-)result is a very good idea.
The Using statement does the Dispose() for you. It does it even if an exception should occur before End Using (There is a hidden Try Finally involved).