39 #include <visp3/core/vpConfig.h> 41 #if (defined(VISP_HAVE_GDI)) 43 #ifndef DOXYGEN_SHOULD_SKIP_THIS 45 #include <visp3/gui/vpGDIRenderer.h> 50 vpGDIRenderer::vpGDIRenderer() : m_bmp(NULL), m_bmp_width(0), m_bmp_height(0), timelost(0)
53 int bpp = GetDeviceCaps(GetDC(NULL), BITSPIXEL);
56 "vpGDIRenderer supports only 32bits depth: screen is %dbits depth!", bpp);
58 InitializeCriticalSection(&m_criticalSection);
107 vpGDIRenderer::~vpGDIRenderer()
110 DeleteCriticalSection(&m_criticalSection);
114 DeleteObject(m_hFont);
123 bool vpGDIRenderer::init(HWND hWindow,
unsigned int width,
unsigned int height)
132 m_hFont = CreateFont(18, 0, 0, 0, FW_NORMAL,
false,
false,
false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
133 CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, NULL);
157 convertROI(I, iP, width, height);
180 convertROI(I, iP, width, height);
186 bool vpGDIRenderer::render()
190 HDC hDCScreen = BeginPaint(m_hWnd, &ps);
193 HDC hDCMem = CreateCompatibleDC(hDCScreen);
196 EnterCriticalSection(&m_criticalSection);
197 SelectObject(hDCMem, m_bmp);
200 BitBlt(hDCScreen, 0, 0, static_cast<int>(m_rwidth), static_cast<int>(m_rheight), hDCMem, 0, 0, SRCCOPY);
202 LeaveCriticalSection(&m_criticalSection);
204 DeleteObject(hDCMem);
206 EndPaint(m_hWnd, &ps);
219 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
222 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
223 imBuffer[i + 0] = I.
bitmap[k].
B;
224 imBuffer[i + 1] = I.
bitmap[k].
G;
225 imBuffer[i + 2] = I.
bitmap[k].
R;
226 imBuffer[i + 3] = I.
bitmap[k].
A;
229 for (
unsigned int i = 0; i < m_rheight; i++) {
230 unsigned int i_ = i * m_rscale;
231 unsigned int ii_ = i * m_rwidth;
232 for (
unsigned int j = 0; j < m_rwidth; j++) {
233 vpRGBa val = I[i_][j * m_rscale];
234 unsigned int index_ = (ii_ + j) * 4;
235 imBuffer[index_] = val.
B;
236 imBuffer[++index_] = val.
G;
237 imBuffer[++index_] = val.
R;
238 imBuffer[++index_] = val.
A;
244 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
259 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
260 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
261 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
262 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
264 int h = i_max - i_min;
265 int w = j_max - j_min;
268 unsigned char *imBuffer =
new unsigned char[w * h * 4];
273 bitmap = bitmap + (int)(i_min * iwidth + j_min);
276 for (
int i = 0; i < w * h * 4; i += 4) {
277 imBuffer[i + 0] = (bitmap + k)->B;
278 imBuffer[i + 1] = (bitmap + k)->G;
279 imBuffer[i + 2] = (bitmap + k)->R;
280 imBuffer[i + 3] = (bitmap + k)->A;
284 bitmap = bitmap + iwidth;
289 for (
int i = 0; i < h; i++) {
290 unsigned int i_ = (i_min + i) * m_rscale;
291 unsigned int ii_ = i * w;
292 for (
int j = 0; j < w; j++) {
293 vpRGBa val = I[i_][(j_min + j) * m_rscale];
294 unsigned int index_ = (ii_ + j) * 4;
295 imBuffer[index_] = val.
B;
296 imBuffer[++index_] = val.
G;
297 imBuffer[++index_] = val.
R;
298 imBuffer[++index_] = val.
A;
304 updateBitmapROI(imBuffer, i_min, j_min, w, h);
318 unsigned char *imBuffer =
new unsigned char[m_rwidth * m_rheight * 4];
321 for (
unsigned int i = 0, k = 0; i < m_rwidth * m_rheight * 4; i += 4, k++) {
322 imBuffer[i + 0] = I.
bitmap[k];
323 imBuffer[i + 1] = I.
bitmap[k];
324 imBuffer[i + 2] = I.
bitmap[k];
328 for (
unsigned int i = 0; i < m_rheight; i++) {
329 unsigned int i_ = i * m_rscale;
330 unsigned int ii_ = i * m_rwidth;
331 for (
unsigned int j = 0; j < m_rwidth; j++) {
332 unsigned char val = I[i_][j * m_rscale];
333 unsigned int index_ = (ii_ + j) * 4;
334 imBuffer[index_] = val;
335 imBuffer[++index_] = val;
336 imBuffer[++index_] = val;
343 updateBitmap(hBmp, imBuffer, m_rwidth, m_rheight);
358 int i_min = (std::max)((
int)ceil(iP.
get_i() / m_rscale), 0);
359 int j_min = (std::max)((
int)ceil(iP.
get_j() / m_rscale), 0);
360 int i_max = (std::min)((
int)ceil((iP.
get_i() + height) / m_rscale), (int)m_rheight);
361 int j_max = (std::min)((
int)ceil((iP.
get_j() + width) / m_rscale), (int)m_rwidth);
363 int h = i_max - i_min;
364 int w = j_max - j_min;
367 unsigned char *imBuffer =
new unsigned char[w * h * 4];
370 for (
int i = 0; i < h; i++) {
371 unsigned int i_ = i_min + i;
372 unsigned int ii_ = i * w;
373 for (
int j = 0; j < w; j++) {
374 unsigned char val = I[i_][j_min + j];
375 unsigned int index_ = (ii_ + j) * 4;
376 imBuffer[index_] = val;
377 imBuffer[++index_] = val;
378 imBuffer[++index_] = val;
383 for (
int i = 0; i < h; i++) {
384 unsigned int i_ = (i_min + i) * m_rscale;
385 unsigned int ii_ = i * w;
386 for (
int j = 0; j < w; j++) {
387 unsigned char val = I[i_][(j_min + j) * m_rscale];
388 unsigned int index_ = (ii_ + j) * 4;
389 imBuffer[index_] = val;
390 imBuffer[++index_] = val;
391 imBuffer[++index_] = val;
398 updateBitmapROI(imBuffer, i_min, j_min, w, h);
414 bool vpGDIRenderer::updateBitmap(HBITMAP &hBmp,
unsigned char *imBuffer,
unsigned int w,
unsigned int h)
418 EnterCriticalSection(&m_criticalSection);
421 if ((m_bmp_width == w) && (m_bmp_height == h) && w != 0 && h != 0) {
423 SetBitmapBits(hBmp, w * h * 4, imBuffer);
430 if ((hBmp = CreateBitmap(static_cast<int>(w), static_cast<int>(h), 1, 32, (
void *)imBuffer)) == NULL)
437 LeaveCriticalSection(&m_criticalSection);
451 bool vpGDIRenderer::updateBitmapROI(
unsigned char *imBuffer,
int i_min,
int j_min,
int w,
int h)
453 HBITMAP htmp = CreateBitmap(w, h, 1, 32, (
void *)imBuffer);
456 HDC hDCScreen = GetDC(m_hWnd);
457 HDC hDCMem = CreateCompatibleDC(hDCScreen);
458 HDC hDCMem2 = CreateCompatibleDC(hDCScreen);
461 EnterCriticalSection(&m_criticalSection);
462 SelectObject(hDCMem, m_bmp);
463 SelectObject(hDCMem2, htmp);
465 BitBlt(hDCMem, j_min, i_min, w, h, hDCMem2, 0, 0, SRCCOPY);
466 LeaveCriticalSection(&m_criticalSection);
469 ReleaseDC(m_hWnd, hDCScreen);
484 HDC hDCScreen = GetDC(m_hWnd);
485 HDC hDCMem = CreateCompatibleDC(hDCScreen);
488 EnterCriticalSection(&m_criticalSection);
489 SelectObject(hDCMem, m_bmp);
494 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
500 LeaveCriticalSection(&m_criticalSection);
503 ReleaseDC(m_hWnd, hDCScreen);
514 unsigned int thickness,
int style)
516 HDC hDCScreen = NULL, hDCMem = NULL;
521 hDCScreen = GetDC(m_hWnd);
524 hDCMem = CreateCompatibleDC(hDCScreen);
526 ReleaseDC(m_hWnd, hDCScreen);
532 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
534 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
535 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
539 ReleaseDC(m_hWnd, hDCScreen);
542 if (!SetBkMode(hDCMem, TRANSPARENT)) {
545 ReleaseDC(m_hWnd, hDCScreen);
550 EnterCriticalSection(&m_criticalSection);
552 if (!SelectObject(hDCMem, m_bmp)) {
553 LeaveCriticalSection(&m_criticalSection);
556 ReleaseDC(m_hWnd, hDCScreen);
561 if (!SelectObject(hDCMem, hPen)) {
562 LeaveCriticalSection(&m_criticalSection);
565 ReleaseDC(m_hWnd, hDCScreen);
573 hDCScreen = GetDC(m_hWnd);
574 hDCMem = CreateCompatibleDC(hDCScreen);
577 hPen = CreatePen(style, static_cast<int>(thickness), m_colors[color.
id]);
579 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
580 hPen = CreatePen(style, static_cast<int>(thickness), gdicolor);
582 SetBkMode(hDCMem, TRANSPARENT);
585 EnterCriticalSection(&m_criticalSection);
586 SelectObject(hDCMem, m_bmp);
589 SelectObject(hDCMem, hPen);
594 if (thickness != 1 && style != PS_SOLID) {
598 double size = 10. * m_rscale;
600 bool vertical_line = (int)ip2_.
get_j() == (int)ip1_.
get_j();
603 std::swap(ip1_, ip2_);
606 std::swap(ip1_, ip2_);
609 double diff_j = vertical_line ? 1 : ip2_.
get_j() - ip1_.
get_j();
610 double deltaj = size / length * diff_j;
611 double deltai = size / length * (ip2_.
get_i() - ip1_.
get_i());
612 double slope = (ip2_.
get_i() - ip1_.
get_i()) / diff_j;
613 double orig = ip1_.
get_i() - slope * ip1_.
get_j();
616 for (
unsigned int i = (
unsigned int)ip1_.
get_i(); i < ip2_.
get_i(); i += (
unsigned int)(2 * deltai)) {
617 double j = ip1_.
get_j();
625 for (
unsigned int j = (
unsigned int)ip1_.
get_j(); j < ip2_.
get_j(); j += (
unsigned int)(2 * deltaj)) {
626 double i = slope * j + orig;
640 LeaveCriticalSection(&m_criticalSection);
644 ReleaseDC(m_hWnd, hDCScreen);
656 void vpGDIRenderer::drawRect(
const vpImagePoint &topLeft,
unsigned int width,
unsigned int height,
const vpColor &color,
657 bool fill,
unsigned int thickness)
662 HDC hDCScreen = GetDC(m_hWnd);
663 HDC hDCMem = CreateCompatibleDC(hDCScreen);
667 COLORREF gdicolor = RGB(0, 0, 0);
670 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
672 gdicolor = RGB(color.
R, color.
G, color.
B);
673 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
679 lBrush.lbStyle = BS_SOLID;
681 lBrush.lbColor = m_colors[color.
id];
683 lBrush.lbColor = gdicolor;
686 lBrush.lbStyle = BS_HOLLOW;
687 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
690 EnterCriticalSection(&m_criticalSection);
691 SelectObject(hDCMem, m_bmp);
694 SelectObject(hDCMem, hbrush);
696 SelectObject(hDCMem, hPen);
705 LeaveCriticalSection(&m_criticalSection);
707 DeleteObject(hbrush);
710 ReleaseDC(m_hWnd, hDCScreen);
717 void vpGDIRenderer::clear(
const vpColor &color)
722 drawRect(ip, m_rwidth, m_rheight, color,
true, 0);
733 void vpGDIRenderer::drawCircle(
const vpImagePoint ¢er,
unsigned int radius,
const vpColor &color,
bool fill,
734 unsigned int thickness)
738 HDC hDCScreen = GetDC(m_hWnd);
739 HDC hDCMem = CreateCompatibleDC(hDCScreen);
744 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
746 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
747 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
752 lBrush.lbStyle = BS_HOLLOW;
753 HBRUSH hbrush = CreateBrushIndirect(&lBrush);
756 int radius_ =
static_cast<int>(radius);
763 EnterCriticalSection(&m_criticalSection);
764 SelectObject(hDCMem, m_bmp);
767 SelectObject(hDCMem, hbrush);
769 SelectObject(hDCMem, hPen);
773 Ellipse(hDCMem, x1, y1, x2, y2);
776 while (x2 - x1 > 0) {
781 Ellipse(hDCMem, x1, y1, x2, y2);
788 LeaveCriticalSection(&m_criticalSection);
790 DeleteObject(hbrush);
793 ReleaseDC(m_hWnd, hDCScreen);
802 void vpGDIRenderer::drawText(
const vpImagePoint &ip,
const char *text,
const vpColor &color)
805 HDC hDCScreen = GetDC(m_hWnd);
806 HDC hDCMem = CreateCompatibleDC(hDCScreen);
809 EnterCriticalSection(&m_criticalSection);
810 SelectObject(hDCMem, m_bmp);
813 SelectObject(hDCMem, m_hFont);
817 SetTextColor(hDCMem, m_colors[color.
id]);
819 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
820 SetTextColor(hDCMem, gdicolor);
824 SetBkMode(hDCMem, TRANSPARENT);
827 int length = (int)strlen(text);
830 GetTextExtentPoint32(hDCMem, text, length, &size);
838 LeaveCriticalSection(&m_criticalSection);
841 ReleaseDC(m_hWnd, hDCScreen);
851 void vpGDIRenderer::drawCross(
const vpImagePoint &ip,
unsigned int size,
const vpColor &color,
unsigned int thickness)
853 int half_size =
static_cast<int>(size / 2 / m_rscale);
860 HDC hDCScreen = GetDC(m_hWnd);
861 HDC hDCMem = CreateCompatibleDC(hDCScreen);
866 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
868 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
869 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
873 EnterCriticalSection(&m_criticalSection);
874 SelectObject(hDCMem, m_bmp);
877 SelectObject(hDCMem, hPen);
893 LeaveCriticalSection(&m_criticalSection);
897 ReleaseDC(m_hWnd, hDCScreen);
911 unsigned int h,
unsigned int thickness)
913 double a = ip2.
get_i() / m_rscale - ip1.
get_i() / m_rscale;
914 double b = ip2.
get_j() / m_rscale - ip1.
get_j() / m_rscale;
924 HDC hDCScreen = GetDC(m_hWnd);
925 HDC hDCMem = CreateCompatibleDC(hDCScreen);
930 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), m_colors[color.
id]);
932 COLORREF gdicolor = RGB(color.
R, color.
G, color.
B);
933 hPen = CreatePen(PS_SOLID, static_cast<int>(thickness), gdicolor);
937 EnterCriticalSection(&m_criticalSection);
938 SelectObject(hDCMem, m_bmp);
941 SelectObject(hDCMem, hPen);
943 if ((a == 0) && (b == 0)) {
988 LeaveCriticalSection(&m_criticalSection);
992 ReleaseDC(m_hWnd, hDCScreen);
1002 unsigned int size = m_rwidth * m_rheight * 4;
1003 unsigned char *imBuffer =
new unsigned char[size];
1006 GetBitmapBits(m_bmp, static_cast<LONG>(size), (
void *)imBuffer);
1009 I.
resize(m_rheight, m_rwidth);
1012 for (
unsigned int i = 0; i < size; i += 4) {
1013 I.
bitmap[i >> 2].
R = imBuffer[i + 2];
1014 I.
bitmap[i >> 2].
G = imBuffer[i + 1];
1015 I.
bitmap[i >> 2].
B = imBuffer[i + 0];
1022 #elif !defined(VISP_BUILD_SHARED_LIBS) 1025 void dummy_vpGDIRenderer(){};
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned char B
Blue component.
Type * bitmap
points toward the bitmap
static const vpColor black
static const vpColor darkRed
Class to define colors available for display functionnalities.
static const vpColor lightGray
static const vpColor darkBlue
unsigned char G
Green component.
static const vpColor green
VISP_EXPORT double measureTimeMs()
static const vpColor lightRed
static const vpColor orange
static const vpColor cyan
static const vpColor lightGreen
static double sqr(double x)
unsigned char A
Additionnal component.
static const vpColor gray
static const vpColor darkGray
static int round(double x)
Error that can be emited by the vpDisplay class and its derivates.
unsigned char R
Red component.
static const vpColor darkGreen
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
static const vpColor yellow
static const vpColor lightBlue
static const vpColor purple
static const vpColor white
unsigned int getWidth() const
static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2)
static const vpColor blue