Skip to content

Add focal point cropping - #48

Closed
TorstenDittmann wants to merge 1 commit into
mainfrom
feat/focal-point-crop
Closed

Add focal point cropping#48
TorstenDittmann wants to merge 1 commit into
mainfrom
feat/focal-point-crop

Conversation

@TorstenDittmann

Copy link
Copy Markdown
Contributor

Summary

  • allow Image::crop() to accept normalized x and y focal coordinates
  • keep the focal point centered where possible and clamp the crop to image bounds
  • preserve the existing gravity behavior when coordinates are omitted
  • validate incomplete and out-of-range focal coordinates

Tests

  • vendor/bin/phpunit --testsuite unit --filter CropFocal (PHP 8.3 + Imagick): 3 tests, 4 assertions
  • vendor/bin/phpstan analyse --level max src tests --memory-limit=512M
  • php -l src/Image/Image.php
  • git diff --check

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

Thanks for contributing! This repository is a read-only mirror; development for this library happens in packages/image in the utopia-php monorepo. Please open this pull request there instead.

@github-actions github-actions Bot closed this Sep 6, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-06T16:01:39.290635Z 374f6b1 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 6, 2026

Copy link
Copy Markdown

Greptile Summary

This PR extends Image::crop() with optional normalized focal coordinates while retaining gravity-based behavior when they are omitted.

  • Validates paired focal coordinates and clamps the crop window to image bounds.
  • Uses explicit positioned scaling and cropping for focal-point requests, including multi-frame images.
  • Adds focal placement and invalid-input tests, with remaining hardening needed for non-finite values and animated focal coverage.

Confidence Score: 4/5

The PR appears safe to merge, with non-blocking hardening needed for non-finite coordinate validation and animated focal-point regression coverage.

The focal geometry and frame lifecycle are consistent with existing crop behavior, but NAN bypasses the new range validation and the animated focal branch lacks direct coverage.

Files Needing Attention: src/Image/Image.php, tests/Image/ImageTest.php

Important Files Changed

Filename Overview
src/Image/Image.php Adds focal-point crop validation, resize geometry, clamped offsets, and frame-aware execution; non-finite coordinates remain accepted.
tests/Image/ImageTest.php Adds basic focal placement and validation coverage but does not exercise the newly reachable animated focal path.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
src/Image/Image.php:114
**NaN Bypasses Coordinate Validation**

The public float parameters accept `NAN`, but comparisons such as `NAN < 0` and `NAN > 1` are false in PHP. This lets a non-finite coordinate reach the crop-offset calculation and produce an unintended crop instead of the expected `InvalidArgumentException`. Reject non-finite coordinates before checking their range.

```suggestion
        if ($x !== null && (!\is_finite($x) || !\is_finite($y) || $x < 0 || $x > 1 || $y < 0 || $y > 1)) {
```

### Issue 2
tests/Image/ImageTest.php:126
**Animated Focal Path Untested**

The successful focal-point test covers only a single-frame PNG, while focal coordinates send animated images through a separate per-frame scale-and-crop path. Add an animated focal-point test that verifies frame dimensions, selected content, and aggregate delay so regressions in this newly reachable path are detected.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat: support focal point cropping" | Re-trigger Greptile

Comment thread src/Image/Image.php
throw new \InvalidArgumentException('Both focal point coordinates are required');
}

if ($x !== null && ($x < 0 || $x > 1 || $y < 0 || $y > 1)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 NaN Bypasses Coordinate Validation

The public float parameters accept NAN, but comparisons such as NAN < 0 and NAN > 1 are false in PHP. This lets a non-finite coordinate reach the crop-offset calculation and produce an unintended crop instead of the expected InvalidArgumentException. Reject non-finite coordinates before checking their range.

Suggested change
if ($x !== null && ($x < 0 || $x > 1 || $y < 0 || $y > 1)) {
if ($x !== null && (!\is_finite($x) || !\is_finite($y) || $x < 0 || $x > 1 || $y < 0 || $y > 1)) {
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Image/Image.php
Line: 114

Comment:
**NaN Bypasses Coordinate Validation**

The public float parameters accept `NAN`, but comparisons such as `NAN < 0` and `NAN > 1` are false in PHP. This lets a non-finite coordinate reach the crop-offset calculation and produce an unintended crop instead of the expected `InvalidArgumentException`. Reject non-finite coordinates before checking their range.

```suggestion
        if ($x !== null && (!\is_finite($x) || !\is_finite($y) || $x < 0 || $x > 1 || $y < 0 || $y > 1)) {
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Comment thread tests/Image/ImageTest.php
$source->drawImage($draw);

$image = new Image($source->getImageBlob());
$image->crop(2, 2, x: 0.75, y: 0.5);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Animated Focal Path Untested

The successful focal-point test covers only a single-frame PNG, while focal coordinates send animated images through a separate per-frame scale-and-crop path. Add an animated focal-point test that verifies frame dimensions, selected content, and aggregate delay so regressions in this newly reachable path are detected.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/Image/ImageTest.php
Line: 126

Comment:
**Animated Focal Path Untested**

The successful focal-point test covers only a single-frame PNG, while focal coordinates send animated images through a separate per-frame scale-and-crop path. Add an animated focal-point test that verifies frame dimensions, selected content, and aggregate delay so regressions in this newly reachable path are detected.

**Knowledge Base Used:**
- [Image manipulation library](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/image/-/docs/image-manipulation-library.md)
- [Animated image processing](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/image/-/docs/animated-image-processing.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 374f6b1c4d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Image/Image.php
throw new \InvalidArgumentException('Both focal point coordinates are required');
}

if ($x !== null && ($x < 0 || $x > 1 || $y < 0 || $y > 1)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject non-finite focal coordinates

When either coordinate is NAN, all four range comparisons evaluate to false, so the value passes validation despite not being between 0 and 1. The subsequent min/max calculation can silently select an image boundary (or produce conversion warnings depending on the PHP version), yielding an incorrect crop; explicitly reject non-finite coordinates before calculating the offsets.

Useful? React with 👍 / 👎.

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.

1 participant