Dynamic images should attempt to resize uncompressed "original" images #10283
Labels
needs:info
[triage] Blocked on missing information
server / core
Issues relating to the server or core of Ghost
When images are uploaded to ghost, we automatically optimize them, and store the original as
filename_o.ext
To avoid double compression, we should be using these optimized images when resizing for dynamic images.
But! It is a little easier said than done, because the
_o
suffix, isn't always a suffix 👻Image optimization
The image optimization we have is a piece of middleware that sits on file upload routes.
When it receives an image
my-image.jpg
it optimizes it (details unnecessary) and asks the StorageAdapter to savemy-image.jpg
(the new optimized image) andmy-image_o.jpg
(the original pre-optimized image)StorageAdapter
The storage adapter base class includes a method called
getUniqueFileName
which takes a requested filename e.g.my-coole-img.jpg
and returns a filename which it can be stored as, the current implementation appends a-n
wheren
is the lowest number that would make the filename unique. e.g.my-coole-img-4.jpg
The problem
The problem lies when we upload an image with a non unique name
already-exists.jpg
,.When we hit the image optimization layer it will ask the StorageAdapter to store
already-exists.jpg
andalready-exists_o.jpg
.The StorageAdapter will find a unique name and so save
already-exists-1.jpg
andalready-exists_o-1.jpg
- This is how the_o
suffix does not always act as a suffix.The solution???
The "easy" route
The easiest solution is a lil regex to match against optimized images
/_o(?:-\d+)?\.[a-zA-Z]+$/
This matches
"_o"
optionally followed by-n
(where n is at least one digit) followed by.ext
where ext is some lettersWhat's wrong with that?
What's wrong with that is that the resize image stuff is really tied to the implementation of the StorageAdapter and how it deals with unique filenames - this is a sign that our code is not structured correctly. If anyone implements a storage adapter with a different unique filename mechanism, this logic will no longer hold.
What else can we do?
We can re-evaluate what the StorageAdapter's responsibilities are, should it handle image optimization?
If it should, then the code can be moved to there, and we can be aware of how files are stored and everything is dandy. (Whether it is part of the base storage adapter, the local file storage adapter, or a brand new one would have to be discussed too - all are viable options IMO)
If it shouldn't then we need to give a nicer API to consumers of the storage adapter so that they can "tag" files with a certain piece of data, e.g "original" or "optimized", whether this is in the form of a suffix or prefix or whatever - I don't know.
This decision will set a precedent for any other manipulation/modifications of storage level data - so if we decide to keep these manipulations outside - we should give a generic and fairly powerful API for modules like the image one to work with.
The text was updated successfully, but these errors were encountered: