Mercurial > hg > orthanc-stone
comparison Applications/Samples/SingleFrameEditorApplication.h @ 351:da25d2423314 am-2
CornerBitmapTracker to crop images
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 26 Oct 2018 17:04:24 +0200 |
parents | c57e049ed079 |
children | d95e65ebe0b9 |
comparison
equal
deleted
inserted
replaced
350:c57e049ed079 | 351:da25d2423314 |
---|---|
308 | 308 |
309 hasSize_ = true; | 309 hasSize_ = true; |
310 width_ = width; | 310 width_ = width; |
311 height_ = height; | 311 height_ = height; |
312 | 312 |
313 | |
314 //SetCrop(0, 0, 2, 2); | |
315 | |
316 | |
317 UpdateTransform(); | 313 UpdateTransform(); |
318 } | 314 } |
315 | |
316 | |
317 unsigned int GetWidth() const | |
318 { | |
319 return width_; | |
320 } | |
321 | |
322 | |
323 unsigned int GetHeight() const | |
324 { | |
325 return height_; | |
326 } | |
319 | 327 |
320 | 328 |
321 void CheckSize(unsigned int width, | 329 void CheckSize(unsigned int width, |
322 unsigned int height) | 330 unsigned int height) |
323 { | 331 { |
367 return (x >= cropX && x <= cropX + cropWidth && | 375 return (x >= cropX && x <= cropX + cropWidth && |
368 y >= cropY && y <= cropY + cropHeight); | 376 y >= cropY && y <= cropY + cropHeight); |
369 } | 377 } |
370 | 378 |
371 | 379 |
380 bool GetPixel(unsigned int& pixelX, | |
381 unsigned int& pixelY, | |
382 double sceneX, | |
383 double sceneY) const | |
384 { | |
385 if (width_ == 0 || | |
386 height_ == 0) | |
387 { | |
388 return false; | |
389 } | |
390 else | |
391 { | |
392 ApplyTransform(sceneX, sceneY, transformInverse_); | |
393 | |
394 int x = static_cast<int>(std::floor(sceneX)); | |
395 int y = static_cast<int>(std::floor(sceneY)); | |
396 | |
397 if (x < 0) | |
398 { | |
399 pixelX = 0; | |
400 } | |
401 else if (x >= static_cast<int>(width_)) | |
402 { | |
403 pixelX = width_; | |
404 } | |
405 else | |
406 { | |
407 pixelX = static_cast<unsigned int>(x); | |
408 } | |
409 | |
410 if (y < 0) | |
411 { | |
412 pixelY = 0; | |
413 } | |
414 else if (y >= static_cast<int>(height_)) | |
415 { | |
416 pixelY = height_; | |
417 } | |
418 else | |
419 { | |
420 pixelY = static_cast<unsigned int>(y); | |
421 } | |
422 | |
423 return true; | |
424 } | |
425 } | |
426 | |
427 | |
372 void SetPan(double x, | 428 void SetPan(double x, |
373 double y) | 429 double y) |
374 { | 430 { |
375 panX_ = x; | 431 panX_ = x; |
376 panY_ = y; | 432 panY_ = y; |
419 | 475 |
420 | 476 |
421 void GetCenter(double& centerX, | 477 void GetCenter(double& centerX, |
422 double& centerY) const | 478 double& centerY) const |
423 { | 479 { |
480 #if 0 | |
424 unsigned int x, y, width, height; | 481 unsigned int x, y, width, height; |
425 GetCrop(x, y, width, height); | 482 GetCrop(x, y, width, height); |
426 | 483 |
427 centerX = static_cast<double>(width) / 2.0; | 484 centerX = static_cast<double>(width) / 2.0; |
428 centerY = static_cast<double>(height) / 2.0; | 485 centerY = static_cast<double>(height) / 2.0; |
486 #else | |
487 centerX = static_cast<double>(width_) / 2.0; | |
488 centerY = static_cast<double>(height_) / 2.0; | |
489 #endif | |
490 | |
429 ApplyTransform(centerX, centerY, transform_); | 491 ApplyTransform(centerX, centerY, transform_); |
430 } | 492 } |
431 | 493 |
432 | 494 |
433 void DrawBorders(CairoContext& context, | 495 void DrawBorders(CairoContext& context, |
695 const ViewportGeometry& view, | 757 const ViewportGeometry& view, |
696 ImageInterpolation interpolation) const | 758 ImageInterpolation interpolation) const |
697 { | 759 { |
698 if (converted_.get() != NULL) | 760 if (converted_.get() != NULL) |
699 { | 761 { |
700 Matrix m = LinearAlgebra::Product(view.GetMatrix(), GetTransform()); | 762 if (converted_->GetFormat() != Orthanc::PixelFormat_Float32) |
701 ApplyProjectiveTransform(buffer, *converted_, m, interpolation, false); | 763 { |
764 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
765 } | |
766 | |
767 unsigned int cropX, cropY, cropWidth, cropHeight; | |
768 GetCrop(cropX, cropY, cropWidth, cropHeight); | |
769 | |
770 Matrix m = LinearAlgebra::Product(view.GetMatrix(), | |
771 GetTransform(), | |
772 CreateOffsetMatrix(cropX, cropY)); | |
773 | |
774 Orthanc::ImageAccessor cropped; | |
775 converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight); | |
776 | |
777 ApplyProjectiveTransform(buffer, cropped, m, interpolation, false); | |
702 } | 778 } |
703 } | 779 } |
704 | 780 |
705 | 781 |
706 virtual bool GetDefaultWindowing(float& center, | 782 virtual bool GetDefaultWindowing(float& center, |
1151 Tool_Move, | 1227 Tool_Move, |
1152 Tool_Rotate, | 1228 Tool_Rotate, |
1153 Tool_Crop | 1229 Tool_Crop |
1154 }; | 1230 }; |
1155 | 1231 |
1232 static double GetHandleSize() | |
1233 { | |
1234 return 10.0; | |
1235 } | |
1236 | |
1156 | 1237 |
1157 BitmapStack& stack_; | 1238 BitmapStack& stack_; |
1158 Tool tool_; | 1239 Tool tool_; |
1159 | 1240 |
1160 | 1241 |
1324 accessor_.GetBitmap().SetPan(dx + panX_, dy + panY_); | 1405 accessor_.GetBitmap().SetPan(dx + panX_, dy + panY_); |
1325 } | 1406 } |
1326 } | 1407 } |
1327 } | 1408 } |
1328 }; | 1409 }; |
1410 | |
1411 | |
1412 class CornerBitmapTracker : public IWorldSceneMouseTracker | |
1413 { | |
1414 private: | |
1415 BitmapStack::BitmapAccessor accessor_; | |
1416 BitmapStack::Corner corner_; | |
1417 unsigned int cropX_; | |
1418 unsigned int cropY_; | |
1419 unsigned int cropWidth_; | |
1420 unsigned int cropHeight_; | |
1421 | |
1422 public: | |
1423 CornerBitmapTracker(BitmapStack& stack, | |
1424 const ViewportGeometry& view, | |
1425 size_t bitmap, | |
1426 double x, | |
1427 double y, | |
1428 BitmapStack::Corner corner) : | |
1429 accessor_(stack, bitmap), | |
1430 corner_(corner) | |
1431 { | |
1432 if (accessor_.IsValid()) | |
1433 { | |
1434 accessor_.GetBitmap().GetCrop(cropX_, cropY_, cropWidth_, cropHeight_); | |
1435 } | |
1436 } | |
1437 | |
1438 virtual bool HasRender() const | |
1439 { | |
1440 return false; | |
1441 } | |
1442 | |
1443 virtual void Render(CairoContext& context, | |
1444 double zoom) | |
1445 { | |
1446 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
1447 } | |
1448 | |
1449 virtual void MouseUp() | |
1450 { | |
1451 } | |
1452 | |
1453 virtual void MouseMove(int displayX, | |
1454 int displayY, | |
1455 double sceneX, | |
1456 double sceneY) | |
1457 { | |
1458 unsigned int x, y; | |
1459 | |
1460 if (accessor_.IsValid()) | |
1461 { | |
1462 BitmapStack::Bitmap& bitmap = accessor_.GetBitmap(); | |
1463 if (bitmap.GetPixel(x, y, sceneX, sceneY)) | |
1464 { | |
1465 unsigned int targetX, targetWidth; | |
1466 | |
1467 if (corner_ == BitmapStack::Corner_TopLeft || | |
1468 corner_ == BitmapStack::Corner_BottomLeft) | |
1469 { | |
1470 targetX = std::min(x, cropX_ + cropWidth_); | |
1471 targetWidth = cropX_ + cropWidth_ - targetX; | |
1472 } | |
1473 else | |
1474 { | |
1475 targetX = cropX_; | |
1476 targetWidth = std::max(x, cropX_) - cropX_; | |
1477 } | |
1478 | |
1479 unsigned int targetY, targetHeight; | |
1480 | |
1481 if (corner_ == BitmapStack::Corner_TopLeft || | |
1482 corner_ == BitmapStack::Corner_TopRight) | |
1483 { | |
1484 targetY = std::min(y, cropY_ + cropHeight_); | |
1485 targetHeight = cropY_ + cropHeight_ - targetY; | |
1486 } | |
1487 else | |
1488 { | |
1489 targetY = cropY_; | |
1490 targetHeight = std::max(y, cropY_) - cropY_; | |
1491 } | |
1492 | |
1493 bitmap.SetCrop(targetX, targetY, targetWidth, targetHeight); | |
1494 } | |
1495 } | |
1496 } | |
1497 }; | |
1329 | 1498 |
1330 | 1499 |
1331 public: | 1500 public: |
1332 BitmapStackInteractor(BitmapStack& stack) : | 1501 BitmapStackInteractor(BitmapStack& stack) : |
1333 stack_(stack), | 1502 stack_(stack), |
1334 tool_(Tool_Move) | 1503 //tool_(Tool_Move) |
1504 tool_(Tool_Crop) | |
1335 { | 1505 { |
1336 } | 1506 } |
1337 | 1507 |
1338 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, | 1508 virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget, |
1339 const ViewportGeometry& view, | 1509 const ViewportGeometry& view, |
1343 double y, | 1513 double y, |
1344 IStatusBar* statusBar) | 1514 IStatusBar* statusBar) |
1345 { | 1515 { |
1346 if (button == MouseButton_Left) | 1516 if (button == MouseButton_Left) |
1347 { | 1517 { |
1348 size_t bitmap; | 1518 size_t selected; |
1349 | 1519 |
1350 if (stack_.LookupBitmap(bitmap, x, y)) | 1520 if (!stack_.GetSelectedBitmap(selected)) |
1351 { | 1521 { |
1352 printf("CLICK on bitmap %ld\n", bitmap); | 1522 size_t bitmap; |
1353 | 1523 if (stack_.LookupBitmap(bitmap, x, y)) |
1354 size_t selected; | 1524 { |
1355 if (stack_.GetSelectedBitmap(selected) && | 1525 printf("CLICK on bitmap %ld\n", bitmap); |
1526 stack_.Select(bitmap); | |
1527 } | |
1528 | |
1529 return NULL; | |
1530 } | |
1531 else if (tool_ == Tool_Crop) | |
1532 { | |
1533 BitmapStack::BitmapAccessor accessor(stack_, selected); | |
1534 BitmapStack::Corner corner; | |
1535 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) | |
1536 { | |
1537 return new CornerBitmapTracker(stack_, view, selected, x, y, corner); | |
1538 } | |
1539 else | |
1540 { | |
1541 size_t bitmap; | |
1542 | |
1543 if (!stack_.LookupBitmap(bitmap, x, y) || | |
1544 bitmap != selected) | |
1545 { | |
1546 stack_.Unselect(); | |
1547 } | |
1548 | |
1549 return NULL; | |
1550 } | |
1551 } | |
1552 else | |
1553 { | |
1554 size_t bitmap; | |
1555 | |
1556 if (stack_.LookupBitmap(bitmap, x, y) && | |
1356 bitmap == selected) | 1557 bitmap == selected) |
1357 { | 1558 { |
1358 switch (tool_) | 1559 switch (tool_) |
1359 { | 1560 { |
1360 case Tool_Move: | 1561 case Tool_Move: |
1362 (modifiers & KeyboardModifiers_Shift)); | 1563 (modifiers & KeyboardModifiers_Shift)); |
1363 | 1564 |
1364 case Tool_Rotate: | 1565 case Tool_Rotate: |
1365 return new RotateBitmapTracker(stack_, view, bitmap, x, y, | 1566 return new RotateBitmapTracker(stack_, view, bitmap, x, y, |
1366 (modifiers & KeyboardModifiers_Shift)); | 1567 (modifiers & KeyboardModifiers_Shift)); |
1367 | 1568 |
1368 default: | 1569 default: |
1369 return NULL; | 1570 break; |
1370 } | 1571 } |
1572 | |
1573 return NULL; | |
1371 } | 1574 } |
1372 else | 1575 else |
1373 { | 1576 { |
1374 stack_.Select(bitmap); | 1577 printf("CLICK outside\n"); |
1578 stack_.Unselect(); | |
1375 return NULL; | 1579 return NULL; |
1376 } | 1580 } |
1377 } | |
1378 else | |
1379 { | |
1380 printf("CLICK outside\n"); | |
1381 stack_.Unselect(); | |
1382 return NULL; | |
1383 } | 1581 } |
1384 } | 1582 } |
1385 else | 1583 else |
1386 { | 1584 { |
1387 return NULL; | 1585 return NULL; |
1393 const ViewportGeometry& view, | 1591 const ViewportGeometry& view, |
1394 double x, | 1592 double x, |
1395 double y, | 1593 double y, |
1396 IStatusBar* statusBar) | 1594 IStatusBar* statusBar) |
1397 { | 1595 { |
1398 static const double HANDLE_SIZE = 10.0; | |
1399 | |
1400 size_t selected; | 1596 size_t selected; |
1401 if (stack_.GetSelectedBitmap(selected) && | 1597 if (stack_.GetSelectedBitmap(selected) && |
1402 tool_ == Tool_Crop) | 1598 tool_ == Tool_Crop) |
1403 { | 1599 { |
1404 BitmapStack::BitmapAccessor accessor(stack_, selected); | 1600 BitmapStack::BitmapAccessor accessor(stack_, selected); |
1405 | 1601 |
1406 BitmapStack::Corner corner; | 1602 BitmapStack::Corner corner; |
1407 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), HANDLE_SIZE)) | 1603 if (accessor.GetBitmap().LookupCorner(corner, x, y, view.GetZoom(), GetHandleSize())) |
1408 { | 1604 { |
1409 accessor.GetBitmap().GetCorner(x, y, corner); | 1605 accessor.GetBitmap().GetCorner(x, y, corner); |
1410 | 1606 |
1411 double z = 1.0 / view.GetZoom(); | 1607 double z = 1.0 / view.GetZoom(); |
1412 | 1608 |
1413 context.SetSourceColor(255, 0, 0); | 1609 context.SetSourceColor(255, 0, 0); |
1414 cairo_t* cr = context.GetObject(); | 1610 cairo_t* cr = context.GetObject(); |
1415 cairo_set_line_width(cr, 2.0 * z); | 1611 cairo_set_line_width(cr, 2.0 * z); |
1416 cairo_move_to(cr, x - HANDLE_SIZE * z, y - HANDLE_SIZE * z); | 1612 cairo_move_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); |
1417 cairo_line_to(cr, x + HANDLE_SIZE * z, y - HANDLE_SIZE * z); | 1613 cairo_line_to(cr, x + GetHandleSize() * z, y - GetHandleSize() * z); |
1418 cairo_line_to(cr, x + HANDLE_SIZE * z, y + HANDLE_SIZE * z); | 1614 cairo_line_to(cr, x + GetHandleSize() * z, y + GetHandleSize() * z); |
1419 cairo_line_to(cr, x - HANDLE_SIZE * z, y + HANDLE_SIZE * z); | 1615 cairo_line_to(cr, x - GetHandleSize() * z, y + GetHandleSize() * z); |
1420 cairo_line_to(cr, x - HANDLE_SIZE * z, y - HANDLE_SIZE * z); | 1616 cairo_line_to(cr, x - GetHandleSize() * z, y - GetHandleSize() * z); |
1421 cairo_stroke(cr); | 1617 cairo_stroke(cr); |
1422 } | 1618 } |
1423 } | 1619 } |
1424 } | 1620 } |
1425 | 1621 |