# Drawing in Images

## Introduction

* Whenever relevant, the **eVision** tools provide methods `Draw` to render their contents and/or configuration. This is, for instance, the contents of an `EImage` or the frame of an `EROI`.
* A given tool can have multiple methods `Draw`, usually one for each feature available.
* The methods `Draw` take an object `DrawAdapter` as their main parameter, and additional parameters for zoom and pan:

  `Tool.Draw(EDrawAdapter* adapter, float zoomX, float zoomY, float panX, float panY);`
  * `zoomX` and `zoomY` are expressed in percentage, 1 is the default value and means no zoom.
  * It can be different in the horizontal and vertical directions (which can be useful in the case of non-square pixels for instance).
  * If you don’t provide a vertical zoom, or set it to 0, it will be set identical to the horizontal one.
  * `panX` and `panY` are expressed in pixels, but in image coordinates. It means that the value you pass to `panX` and `panY` are multiplied by the corresponding zoom before being applied.

Example: How to draw an image and a ROI frame on a window under Windows:

```c
EImageBW8 image;
EROIBW8 roi;
EWindowsDrawAdapter adapter(windowHdc);
image.Draw(adapter);
roi.DrawFrame(adapter);
```

## Graphical interactions

* You can configure some of the **eVision** tools graphically and use the provided methods to put your configuration in place.
* Graphical Interaction-enabled tools provide special parameters to some of their methods `Draw` to draw handles on the tool representation.
* To capture the user interactions with those handles, these tools also provide two specialized methods:
  * `HitTest` detects if a handle is under the mouse when providing it with the current cursor coordinates. You typically use this test during a mouse button down event.
  * `Drag` moves the detected handle to the given coordinates. This in turn modifies the tool configuration to match the new handle position. `Drag` is typically associated with the mouse button up event.

  #### NOTE
  `HitTest` and `Drag` use the same zoom and pan parameters as `Draw`. You must set them the same way (with the same values) to achieve the desired result.
* Use [`Easy::GetHandleSize`](../../../doxygen_cpp/classeVision_1_1Easy.html#ac44de38a44253d25ae8da454bac056a0) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1Easy.html#ad1482696d2235789c5dfe7c48b6c7c4d) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1Easy.html#ad4d68bfb0c661864c0e1671619b9272f) to change the handle size.
  * This value influences the drawing and the hit area.
  * By default, the handle size is equal to 8 pixels.

## Draw adapters

* The draw adapters are objects that, in addition to representing the context in which to draw, provide methods to draw the selected primitives in that context.
* They are initialized by providing the targeted context to the constructor.
* Some of the drawing methods provided by the draw adapters are (but are not limited to):
  * [`EDrawAdapter::Line`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#aca27509b509ada30bb57981b987a9434) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a853bc1d9319d91bd5a098ab5e4d83980) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#aaee796951b1bf140f6fdbdcf3d1b2fd0) / [`EDrawAdapter::Line`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#aca27509b509ada30bb57981b987a9434) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a853bc1d9319d91bd5a098ab5e4d83980) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#aaee796951b1bf140f6fdbdcf3d1b2fd0) draws one or more lines on the context
  * [`EDrawAdapter::Rectangle`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#ab4c1a33f7962e0810d60fd327cfe4bcd) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a3352c5438f88290d05f108fecb9fa3e8) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#abf8428df0a51e76ba786e04b25870c55) / [`EDrawAdapter::FilledRectangle`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a68578ba928468636fed418b81abd14a8) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#acf140c6de5497fca1b423ee565f974ff) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a85c647e8a572dd04e69942e39682500c) draws a rectangle, filled or not, on the context
  * [`EDrawAdapter::Ellipse`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a109b7cfc5f7b21f90150f5659af0e1a1) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a8de20b4fc545a0f8db8251922b10d785) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a81b31d43de2a55956fb9ffd3ed76ed3e) / [`EDrawAdapter::FilledEllipse`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a45b09b0a2223d823eb8ec1d794efbe7c) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a4ac663135e43b607ddca88f0bdd09454) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#ace6ad0248ef527ef5ef6f80af8fe5d46) draws an ellipse, filled or not, in the context
  * [`EDrawAdapter::Text`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a984f04de86845405575f33992a7d3279) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a57d60055a67d8d857c2890e5174fb711) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a5f03c973b826945c6cad75f5a53a7803) / [`EDrawAdapter::BackedText`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a5e47bc04ed79bff6dd1f81c04408bac9) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a4182d7aa2a319eba32bdaf77dcac7314) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#abf535a5c825d4b14593b9f9688087c82) renders a text in the context, with or without background
  * [`EDrawAdapter::Image`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a3212e737fc15d706d870ece4c4d6f363) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#ae354df2358072d5576be31622f07a2d5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a49de18122c8bc820557816e3480083d3) renders an image in the context
* For more information about the drawing primitives provided by the draw adapters, please refer to the reference documentation.
* To set the color of the primitives, provide a pen and/or a brush and use the methods [`EDrawAdapter::GetPen`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#afcd8feaba3aedc66c7afdc88866dc39d) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a187d7736e9c416688fb7ff744b21ebb5) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a4a20253fa981c50ed35fe082cab5b768) and [`EDrawAdapter::GetBrush`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a6cde134369af812642fe826b4461d3a4) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a578afc3cce5de16dcc03b063a22f9430) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#af4507471ffa72255aa0a6951d9e1e1f4).
  * If you do not provide a pen and/or a brush, the default colors are used.
* The set the font of the text, provide a font with the method [`EDrawAdapter::GetFont`](../../../doxygen_cpp/classeVision_1_1EDrawAdapter.html#a8a37a6d4ab1ed9298f413513033a6348) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EDrawAdapter.html#a9d26d5851cff03fc920fa055ce90d1de) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EDrawAdapter.html#a883b6fea88599c8df9e13f71a270eb18).

## Standard draw adapters

**eVision** provides a set of off-the-shelf draw adapters that you can use in different situations:

* [`EWindowsDrawAdapter`](../../../doxygen_cpp/classeVision_1_1EWindowsDrawAdapter.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EWindowsDrawAdapter.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EWindowsDrawAdapter.html) allows to draw on **Windows** systems. To draw on a window, provide the window’s HDC to its constructor, or, to draw in an `EImage` buffer, provide that `EImage`.
  * It relies on GDI and GDI+ to provide its services.
  * This is the preferred way to draw on **Windows**.
* `QtDrawAdapter` allows you to draw using **Qt** on a QPainter context. To draw on a QPainter context, provide the QPainter to the constructor, or, to draw on an `EImage` buffer, provide that `EImage`.
  * You can use the `QtDrawAdapter` both on **Windows** and **Linux**.
  * This is the preferred way to draw on **Linux**.

    #### NOTE
    `QtDrawAdapter` is using an external resource (namely **Qt**) and as such is provided as source code in its own header rather than in the global **eVision** header. For more information about external and custom draw adapters, see below.
* [`EGenericDrawAdapter`](../../../doxygen_cpp/classeVision_1_1EGenericDrawAdapter.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EGenericDrawAdapter.html) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1EGenericDrawAdapter.html) is a draw adapter that can only render on an `EImage`, but it can do it in a consistent manner on all supported OSes.
  * It is available on both **Windows** and **Linux**.

## Drawing in an `EImage`

* As said above, you can draw in an `EImage` (usually an `EImageBW8` or `EImageC24`) by initializing a draw adapter with that image and using either the **eVision** methods `Draw` or the draw adapter drawing primitives:

```c
EImageBW8 image;
EMatrixCode code;
EWindowsDrawAdapter adapter(image);
code.DrawPosition(adapter);
```

## Custom draw adapters

* If you require a draw adapter to render in a specific, unsupported type of context (for ex. a DirectDraw surface, an OpenGL context…), you can build your own draw adapter by deriving from the interface [`EExternalDrawAdapter`](../../../doxygen_cpp/classeVision_1_1EExternalDrawAdapter.html) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1EExternalDrawAdapter.html) provided by **eVision** and implementing all the required methods.
* Once this work is done, you will be able to use your new, custom draw adapter in the same way as the off-the-shelf ones, taking advantage of **eVision** methods `Draw`.
* The provided `QtDrawAdapter` is a draw adapter built using that mechanism, you can use it as a reference on how to build a custom draw adapter. The sources of the `QtDrawAdapter` are bundled with the Qt Samples.

## Enhanced Image Display

When the enhanced image display mode is enabled, a high-quality interpolation method is used to display the resized images.

* Set [`Easy::SetEnableEnhancedImageDisplay`](../../../doxygen_cpp/classeVision_1_1Easy.html#aa75839fa4d94d9f67ee5e0fef377d580) [<sub>.NET</sub>](../../../doxygen_cs/classeVision_1_1Easy.html#ae8b26f7ac6b29612431a2613d96f43ce) [<sub>Python</sub>](../../../doxygen_python/classeVision_1_1Easy.html#a94b041e904a01cdfa8618a903305e84c) to `TRUE`, to enable the enhanced image display.
* By default, this option is disabled.
* Enhanced image display has a significant impact on display speed, the drawing can be 4x to 10x slower.
* The drawing of images with `EBW8Vector` or `EC24Vector` used as Look Up Table doesn’t support enhanced image display

![image](assets/images/manipulating/image_drawing_and_overlay_1.webp)
* **eVision Studio** exposes this option in `View` > `Option` dialog:

![image](assets/images/manipulating/image_drawing_and_overlay_2.webp)
