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