I have a 1.6 megapixel camera and would like to display the camera images 1:1 in a display control (so without zooming, no scrollbars and so on). Ho do I go about this?
Hi, which framework are you targeting?
Hi @mickybela,
This is actually a lot more difficult than it sounds and the way to achieve it differs depending on the GUI toolkit that you are using (hence @parsd’s question). Besides getting the settings of the :cvb: display control right there are two major obstacles that need to be tackled to implement a proper 1:1 display:
- The notion of size of any given GUI toolkit does not necessarily correspond to pixel sizes. VB6 used “twips”, MFC uses “dialog base units”. Forms and WPF in general use size in screen pixels - but Forms may scale depending on the system font size and both may scale depending on the screen’s DPI settings - so all of these factors need to be taken into account.
- Not matter how well you tune your settings and the dialog size, the display control will always paint a 3 pixel border around the client area in the control’s current
Background
color.
Let me give an example based on Windows Forms - much of it maps to other GUI toolkits without much effort, only the dialog size part is harder to get right with some of them. Assuming that you want to open a form that shows an image in 1:1 scaling, this is what you need to do:
-
Disable every option on the display control that would produce additional padding:
- Set the
BevelInner
andBevelOuter
property tofalse
. This will eliminate the pseuso-3D-appearance of the display control’s client area. - Set
StatusCurrentPos
,StatusScale
,StatusGrayValue
,StatusEmpty
,StatusImageSize
andShowCoords
tofalse
and make sure thatStatusUserText
does not contain anything. This will make sure that the status bar disappears. (If you want to display your image at 1:1 scale and still use the status bar, please add another 16 pixels to height) - Set the
ScrollBars
property tofalse
to prevent scroll bars from showing if the user zooms into the display (you may use theLeftButtonMode = LB_PAN
to make sure your user can still move around on the display after he/she zoomed in).
- Set the
-
Set the Display control’s
BackColor
property to something you are not expecting to see anywhere else in your application. Magenta is a typical choice for this (don’t worry about the fact that setting “Magenta” in theBackColor
property won’t stick and turn into “Fuchsia” instead - that’s just a side effect of converting toOLE_COLOR
inside the control and will not defeat the purpose of setting that color). -
Set the
TransparencyKey
property of your form to the background color that has been defined in the previous step. This will make the accordingly colored regions in the window transparent (namely the 3 pixel border around the display). -
Make sure you are using a borderless form (
FormBorderStyle = None
). I have no idea why, but when using other settings for the form border, setting the form’s size will not exactly set the form’s size to the values you specified (e.g. with aSizable
border you’ll get a window of 1017x1010 pixels when specifing a size of 1024x1024, plus you’ll have to deal with the window’s title bar).Step 2 to 4, are only necessary if you want to display a seemingly borderless 1:1 representation of your image in a window of its own. If, instead, the image is supposed to be part of a form rather than occupy the form all alone, then you’d need to modify this approach slightly. In this case I suggest using panels to organize layout and make sure that the display’s parent panel is sized properly (i. e. either at a size of
width + 6
andheight + 6
and accepting the 3 pixels padding region it produces by default or usingwidth
andheight
as they are and setting negative location values like below). -
In your initialization code for the form, modify the width and height of the form to accomodate the entire image:
Width = Cvb.Image.ImageWidth(img); Height = Cvb.Image.ImageHeight(img);
-
Modify the location and size of the display control extend slightly (3 pixels…) beyond the parent form/control’s extent:
theDisplay.Left = -3; theDisplay.Top = -3; theDisplay.Width = Width + 6; theDisplay.Height = Height + 6;
Done. The following little project illustrates the approach: GenuineScaleDisplay.zip (167.7 KB)
Just as an addition to @illusive’s solution: the Stemmer.Cvb.Wpf Display does not add a border if you don’t. Also, I think, the Qt Display doesn’t add one either.
True. I read “in a control” as a reference to the ActiveX control, hence the suggested path. But you’re right, these would also do the trick.
This also explains the top = -3 and left =-3 properties in the fullscreen .net example. Always wondered about that one. Thanks