-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add smart image cropping with Computer Vision #149
Conversation
* | ||
* @return int | ||
*/ | ||
function computer_vision_max_filesize() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved these functions out of the ComputerVision class because they're now called from multiple places and don't use ComputerVision class state.
* @param string The request URL with query args added. | ||
* @param array Array containing the image height and width. | ||
*/ | ||
do_action( 'classifai_smart_cropping_unsuccessful_response', $response, $url, $data ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use the failed response for #143
In regards to Alternate Designs 1: "I considered deleting the original non-smart-cropped file when Computer Vision successfully returns a cropped image. This would save server space. I'm still on the fence about it.", I think I'm on the side of the fence of deleting the original non-smart-cropped file as I'm not sure there would be an easy way for a site owner to swap that back into place of the smart-cropped file and its not as though we're deleting the main source image itself. |
In regards to Alternate Designs 2: "I also considered adding a checkbox group on the settings page allowing the feature to be opted into on the basis of specific image sizes, but this felt too complex. I did introduce a couple of filters that could be used to turn off smart-cropping specific image sizes.", I agree with the lesser complexity of the single checkbox on the settings page and that providing filters seems the better route for flexibility. |
Hi team, Did some initial tests with Azure Blob Storage to ensure that images could be smart cropped even when offloaded to external service. Good news: Initial images under 4MB get smart cropped with Azure Blob Storage If the initial image is over 4MB and needs to go through @filesize to check server side file size it does not get smart cropped. |
@rickalee thanks for the testing and feedback... any immediate advice for @johnwatkins0 on tweaks to ensure that images that go through the 4mb file size checks properly get through the smart cropping? |
Add a check for file_exists when using get_attached_file() if not try wp_get_attachment_url() Note: With Azure Blob Storage we sometimes proxy example.com/wp-content/uploads/ to Azure Blob so URLs returned from wp_get_attachment_url() may not obviously be Azure Blob. One alternative would be to add a filter to response headers to determine source e.g. |
Thanks, @rickalee . For testing purposes, do you use https://github.com/10up/windows-azure-storage to integrate Azure storage, or something else? |
@johnwatkins0 That plugin is correct. |
Hi, @rickalee, after taking a closer look, I think this can be solved easily. I am weighing a few options, though, and would welcome your thoughts (also CC the reviewers on this PR). This issue is not with cropping in particular but rather the For cases of remote storage, we need an alternative. Here's what I'm considering:
Thanks! |
@johnwatkins0 I think option #1 with filter before get_largest_acceptable_image_url is path of least resistance. Although I'm curious if we should look into 5.3 behavior with Big Images and try and add our hooks after the -2560 crop is generated. Anecdotally big image as is in 5.3 cut original 6.1MB image down to 589kb. https://make.wordpress.org/core/2019/10/09/introducing-handling-of-big-images-in-wordpress-5-3/ |
Good idea, @rickalee . I'll see if that can be the solution for 5.3+, with the filter for pre-5.3. |
@jeffpaul The need for smart cropping in WordPress has come up in some client conversations lately, including in one fast-moving project with a late-winter launch date. Is there anything I can do to help move this along and maybe get it into the plugin in time? |
@johnwatkins0 I'm hoping that we can finish up some other work here in January so that we shift focus to getting the ClassifAI 1.5 release out in February. Is that timing too slow for what you're hoping for? @rickalee have you had a chance to review John's latest updates to see if they play well with Azure blob storage such that you can 👍 this PR? |
Thanks, @jeffpaul . February would give us plenty of time. |
return false; | ||
} | ||
|
||
$data = array( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should change it to php 5 array.
In my test, the PR works great without Azure Storage. But when I use Azure storage, there are still some issues:
|
return true; | ||
} | ||
|
||
/** | ||
* Register the functionality. | ||
*/ | ||
public function register() { | ||
add_filter( 'wp_generate_attachment_metadata', [ $this, 'process_image' ], 10, 2 ); | ||
add_filter( 'wp_generate_attachment_metadata', [ $this, 'smart_crop_image' ], 10, 2 ); | ||
add_filter( 'wp_generate_attachment_metadata', [ $this, 'generate_image_alt_tags' ], 10, 2 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my test, changing these filters priority to 8
get image tagging and smart cropping work with Azure Storage which hooks to the same filter with priority set to 9
.
@johnwatkins0 are you able to work through the feedback from @Ritesh-patel and @dinhtungdu? If not, I'll see if someone else can help wrap up these so the PR is ready for the v1.5 release. |
@jeffpaul Yes, I can work on it over the next few days. |
Thanks, @dinhtungdu . I have pushed the suggested changes. In my test environment using Azure storage I have uploaded an image and verified that the 150x150 thumb is smart-cropped and that the alt text is generated. Let me know if you find any other issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cropping function works flawlessly locally.
This PR doesn't work with Azure storage because of get_largest_acceptable_image_url()
. Because that function exists before this request, we should work on the Azure storage issue in other PR.
@@ -84,18 +115,19 @@ public function get_max_filesize() { | |||
* | |||
* @return mixed | |||
*/ | |||
public function process_image( $metadata, $attachment_id ) { | |||
public function generate_image_alt_tags( $metadata, $attachment_id ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is doing both alt and tag generation. IMO, we should
- Use better name
- Or even better, split the public method to do only one task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dinhtungdu just to add some context here. This function handles both items because the results of scan_image
return both the captions and tags. The actual creation for tags and alts tags are done by separate functions called by this function. This is a long-winded way of saying that we save another call to the service by doing this all at once.
I'd be for a name change to the function to better reflect what it does though :)
* @param int $max The maximum acceptable size. | ||
* @return string|null The image URL, or null if no acceptable image found. | ||
*/ | ||
function get_largest_acceptable_image_url( $full_image, $full_url, $sizes, $max = MB_IN_BYTES ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function return NULL
with Azure storage enabled and configured. Tested with publicly accessible WP install and newly uploaded images after configuring Azure.
); | ||
$this->assertNull( $url ); | ||
|
||
remove_filter( 'classifai_computer_vision_max_filesize', $set_1kb_max_filesize ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nitpick here, if the test fails, this filter won't be removed. I'd recommend moving it up before the $this->assertNull
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@jeffpaul @dinhtungdu I think we can land this feature now and then focus on the Azure Storage integration as an immediate followup. Any concerns with that approach? |
@ryanwelcher No concern, I agree! |
This PR introduces smart image cropping provided by Computer Vision.
It would resolve #112. I think #135 could integrate smart cropping without much additional effort.
Description of the Change
Sites are opted into the service through a checkbox on the image processing settings page. As an image is uploaded, each intermediate image size with cropping generates a request to the external service. If a cropped image is successfully returned, that image is saved and added to the image metadata in place of the version generated by WordPress (which remains in the file system).
Alternate Designs
Benefits
Thumbnails are nicely cropped around faces and other focal points.
Possible Drawbacks
A separate request needs to be made for each cropped image size. Only one core image size is cropped by default, but themes/plugins can register any number of cropped sizes. I think at some point the external requests around image processing are going to need to be done asynchronously rather than during pageload execution.
Verification Process
This only works on a publicly accessible site.
Checklist: