-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
ImageMedium#derivatives now works with image filters #1035
Conversation
Previously, using ImageMedium->derivatives would not work well in combination with image filters or the other method of generating srcset variants of images (by appending eg. "@2x" to their filenames). This commit hopefully fixes that.
@@ -119,8 +119,8 @@ public static function scaledFromMedium($medium, $from, $to) | |||
} | |||
|
|||
$ratio = $to / $from; | |||
$width = (int) ($medium->get('width') * $ratio); | |||
$height = (int) ($medium->get('height') * $ratio); | |||
$width = $medium->get('width') * $ratio; |
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 isn't directly related to the original intention with this PR, but I've previously found that downscaled images sometimes got a white stripe at the far right edge. Not rounding the pixel values sent to Gregwar/Image fixed that
Wow this is the nicest documented PR I've ever received. Love it! Will review and test. |
Thanks! :) The changes so far did fix the fact that general image operations weren't applied to derivatives, but I found that I stumbled a bit with the "@2x" filename plus the derivatives method, it's not working quite the way I wanted it to just yet. I'm working on it now, so will hopefully push another commit pretty soon! |
The biggest alternative will now become the base medium, and alternatives will be filled out as necessary in a descending manner.
@rhukster alright, I've pushed another commit. Hopefully that should do it! |
Otherwise we get some funky results, with the possibility of two different images being rendered between the full-width srcset version and the original src version.
616ccf6
to
4d19620
Compare
Sorry got busy this past week.. will check this out soon. |
} | ||
|
||
$derivative = MediumFactory::fromFile($this->get('filepath')); | ||
$derivative_width = $derivative->get('width') * $ratio; |
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.
I've been using this fork for my own project, and I've run across an error on this row a few times. MediumFactory::fromFile
seems to have returned null, presumably because $this->get('filepath')
in turn returned null. Both times this happened was after I had removed content, and the problem went away by restarting the php-fpm
service on the server, so I suspect Grav has somehow cached the content associated with a page and then runs into an error.
Does this seem like a separate issue, or do we need to check to ensure the filepath isn't null or something here?
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.
There is a check in the first line of that Medium::fromFile()
method that checks the file exists, it returns null
if not, so probably at least need to check for null before using $derivative
.
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.
Hmm, I see. How come a medium can be constructed in the first place if the corresponding file doesn't exist? I mean, if MediumFactory
calls file_exists
, how come the Media
class that assembles page media doesn't?
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.
Let me know if you want me to add a null check here or if it'd better to make changes further up the hierarchy, @rhukster!
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.
Some more details on the issue I've been experiencing here. I'm debugging this right now, but for reference, or if anyone has a good idea of what might cause this:
I get an issue here after having synced new content to the server with rsync from my OS X El Capitan desktop to the Ubuntu 16.04 server. It looks like some of the files that rsync synchronizes are turned from having some uppercase letters in the filename to all lowercase. For some reason, Grav doesn't pick up on this, and still believes that the filenames are the same as they used to be - ie. they contain some uppercase letters. So Grav/PHP is partly right - the file does exist, just not with that exact filename.
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.
Alright, getting through this was a real ordeal, but it looks like I figured out what the issue was.
At first I thought it was PHP that was returning errant results when listing the contents of a directory, but it turns out that it was Grav's page object caching mechanism that didn't pick up on updates to just the media files of a page object. I described this issue in #1080 as well.
Media::__construct
(which initializes a page's media), is allowed to continue even if MediumFactory::fromFile
returns null. This patch doesn't take that risk into account, and IMO, it shouldn't either. If the original ImageMedium
was initiated, it should reliably point to an actual file.
Would be awesome if we could work through this final issue and get this PR merged, @rhukster!
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.
If the cache is working as intended and it's a conscious convention to return null when the image can't be found, then we should probably check if the method call returned null. But in that case maybe we can have a discussion about how the caching mechanisms can be clarified in the docs (but that's better done in #1080).
@rhukster I've pushed another commit that accounts for the risk of the image derivatives being generated from a cached ImageMedium instance and the original file no longer existing. I've also verified that this works (it results in an "error" image in the browser). This should hopefully be good for a merge now! |
When using naming conventions to generate image alternatives, this patch would previously generate a “@1x” alternative if one didn’t exist. That’s no longer the case
One more fix! I've been testing out this patch a lot recently, and it's worked well for me. But I realized that with pre-generated responsive image alternatives, it would auto-generate an "@1x" alternative if such a file wasn't found. I've fixed that now so that the first image alternative it looks for is "@2x" |
So I was able to test this PR out and it there's something weird with the old 'alternative' style @2x, @3x syntax. For example, my test in Develop branch with a @3x image yields:
Your PR branch for the same page yields:
I added some line breaks for clarity. But before it uses the smallest image for the In yours, it serves up the original 'largest' image in the |
BTW you might want to merge in this commit: 31e358c It adds the correct 'prettyname' to the generated alternative images.
This is the same example as above. |
Btw another commit (92401de) fixes the issue with the increasing hashing when you append operations..results look better now:
|
I knew it was going to bite me sooner or later that I forgot to do this in a feature branch... I've pushed a fix for the problem you described as well as merged your changes from |
My original motivation for writing this PR was the problem described in #1016, where using the
derivatives
method on an image in a Twig template wouldn't work well in combination with the other method of producing responsive images in Grav - appending a pixel density indicator to the image's filename (eg. "@2x").The underlying problem here also meant that image filters would not work in combination with image derivatives. They would work with image alternatives, which is what was generated from appending "@2x" to the filename of the image, but it wouldn't work with derivatives.
This commit fixes both the first and the second problem by making it so that the ImageMedium#derivatives method doesn't add image variants to a separate array, but rather to the same array as it would have if the filename method was used.
I've made some line comments to highlight a few things in the code as well!