Skip to content

Fix Multiple Bugs in Crop Functionality#284

Merged
Ruben2776 merged 2 commits intoRuben2776:devfrom
Aolinlu:dev
Dec 9, 2025
Merged

Fix Multiple Bugs in Crop Functionality#284
Ruben2776 merged 2 commits intoRuben2776:devfrom
Aolinlu:dev

Conversation

@Aolinlu
Copy link
Contributor

@Aolinlu Aolinlu commented Dec 9, 2025

Description

While using PicView's "Crop" feature, I encountered several bugs and have attempted to fix them in this PR. Here is a brief introduction to the issues:

1. TextBlock Overlap at Top Edge:
When the crop area is close to the top edge of the window, the TextBlock displaying the crop dimensions is partially covered, making the values hard to read.

image

2. TextBlock Overlap at Right Edge:
When the crop area is close to the right side of the image, the TextBlock is also partially covered, making it impossible to view the values.

image

3. Incorrect Initial Crop Size for Small Images:
For images with small dimensions, the initial crop area size is incorrect. For example, after clicking the crop button, the initial width may be 537, while the image itself is only 300 pixels wide. At the same time, in the incorrect case, the crop area’s left and right borders are not visible, as they are clipped outside the image bounds.

image

Comparing the two pictures above and below, it is clear that the left and right boundaries of the cropped area in the top picture (the white line) are not visible.

image

4. Crop Area Size is (0, 0) for Certain Resolutions:
For images within a specific resolution range, the default crop area size is set to (0, 0).

image

Bug Analysis and Fixes:

1. Top Edge Overlap:

The calculation for the TextBlock position only handled the case when topLeftY == 0, ignoring the thickness of the TextBlock itself.
Original code:

if (topLeftY != 0)
{
    Canvas.SetTop(control.SizeBorder, topLeftY - control.TopLeftButton.Bounds.Height);
}
else
{
    Canvas.SetTop(control.SizeBorder, topLeftY);
}

Fix:

Update to:

Canvas.SetTop(control.SizeBorder, Math.Max(0, topLeftY - control.TopLeftButton.Bounds.Height));

This ensures the TextBlock is always visible.
PicView_FDxDVnkzsH

2. Right Edge Overlap:
For large images, you can calculate the TextBlock width and adjust its left position using SetLeft. However, for very small images, the TextBlock will inevitably be clipped. Therefore, I suggest changing the parent container’s ClipToBounds property to False:

ClipToBounds="False"
image

3 & 4. Incorrect Initial Crop Size:

These bugs are due to incomplete logic in CropLayoutManager initialization.

Original code:

   var pixelWidth = vm.PicViewer.ImageWidth.CurrentValue / vm.PicViewer.AspectRatio.CurrentValue;
   var pixelHeight = vm.PicViewer.ImageHeight.CurrentValue / vm.PicViewer.AspectRatio.CurrentValue;
   if (pixelWidth >= DefaultSelectionSize * 2 &&
       pixelHeight >= DefaultSelectionSize * 2)
   {
       vm.Crop.SetSelectionWidth(DefaultSelectionSize);
       vm.Crop.SetSelectionHeight(DefaultSelectionSize);
   }
   else if (pixelWidth <= DefaultSelectionSize &&
            pixelHeight <= DefaultSelectionSize)
   {
       vm.Crop.SetSelectionWidth((uint)(pixelWidth / 2));
       vm.Crop.SetSelectionHeight((uint)(pixelHeight / 2));
   }

Problems:

When DefaultSelectionSize < pixelWidth < DefaultSelectionSize * 2, there is no logic, resulting in crop area width/height being zero.

Since the current DefaultSelectionSize is set to 200, if an image has a resolution between 200 and 400 (for example, 350 × 350), this will trigger the bug where the initial crop area size is zero.

The crop size should be based on ImageWidth, not pixelWidth. For example, if pixelWidth = 300 but the displayed ImageWidth is only 118 due to scaling, the initial crop width should not exceed 118 / 2.

Fix:

   var originalWidth = vm.PicViewer.ImageWidth.CurrentValue >= DefaultSelectionSize * 2
       ? DefaultSelectionSize
       : (uint)(vm.PicViewer.ImageWidth.CurrentValue / 2);
   var originalHeight = vm.PicViewer.ImageHeight.CurrentValue >= DefaultSelectionSize * 2
       ? DefaultSelectionSize
       : (uint)(vm.PicViewer.ImageHeight.CurrentValue / 2);
   vm.Crop.SetSelectionWidth(originalWidth);
   vm.Crop.SetSelectionHeight(originalHeight);
image

How Has This Been Tested?

Maybe this can only be tested manually?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • My code follows the code style of this project.

@Ruben2776 Ruben2776 self-requested a review December 9, 2025 10:02
@Ruben2776
Copy link
Owner

Thank you very much, it looks great!

Maybe this can only be tested manually?

Currently, only manual testing has been set up. I'm gradually working on moving code-behind into MVVM to make the code cleaner and more maintainable, which should also theoretically allow the project to be testable.
As it is now, there is the PicView.Test solution that is supposed to be for unit testing. I have unfortunately not gotten around to actually making it work yet, but it is a future goal.

Any help from anyone would be greatly appreciated.

@Ruben2776 Ruben2776 merged commit d760f2a into Ruben2776:dev Dec 9, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants