Cloudifying images on svenska.yle.fi

Yle’s internal Image Management System (IMS) was recently renewed. It was a big leap forward for the site svenska.yle.fi to move all its images to the cloud, not only for the storage but for all the transformations as well.

Background
IMS is a custom, PHP based solution for storing images in a central place. It supports uploading and cropping images as well as managing image information such as tags, alt text and copyright. Images may be searched by tags or upload date. The system is multilingual, currently supporting English, Finnish and Swedish.

IMS was born about 5 years ago in December 2008, when the first version of it was launched. It was a quite simple looking tool for uploading and searching images. The workflow was to upload an image, enter its information such as tags and copyright, select its crop area(s) and save it. Then an editor would select the image while writing an article in SYND, FYND or any of the older now migrated sites. The image id is saved in the article, and the image is displayed via IMS. This way the same image may be reused in multiple articles.

Different image sizes for each image are needed depending on where the images are displayed on the site. IMS had a custom made, JavaScript based cropping tool for selecting the crop area of the image. The alternatives were to use the same crop area for all different image sizes, or to crop each size separately. The result was that we had 10 image files stored per uploaded image: The original plus the cropped version in nine different sizes ranging between 640x360px and 60x60px. All of there were in ratio 16:9 with the exception of the last one which was 1:1.

Cloudification
Along with Yle’s new Images API, the new version of IMS serves images from a cloud service. All transformations are done on the fly by specifying parameters in the image URL. Therefore, no actual image crops are performed on our servers anymore, we only save the crop coordinates (as a string in our database) and relay them to the cloud.

IMS also supports choosing crop areas for different image ratios now, instead of for different sizes. Available ratios to choose from are 16:9, 2:3 and 1:1.

When uploading an image, the image is first uploaded locally to our server. It is given a public id (used as a resource identifier by the cloud service), which, along with other information related to the image, is saved to our database. After that we tell Images API where the image is located and what public id it has. The image is fetched from it location and pushed to the cloud service. Now we can start using our image directly from the cloud, and that is exactly what we do next.

Once an image has been uploaded, the user is redirected to the image editor view. Already here, the image shown is served from the cloud and scaled down to an appropriate size just by adding a scale parameter in the image URL. The user may now define how the image should be cropped in each available ratio, enter some tags, alt-text etc. For increased SEO, we actually save the given tags and copyright text into the image file itself, in its IPTC data. This means, however, that each time the values are changed, the image has to be sent to the cloud again, replacing the old one.

Drupal integration
We have a Drupal module integrating with IMS in order to fetch images from it. In the Drupal frontend we initially always render a 300px wide image in order to show the users some image almost instantly, even though it would be very blurry as it might be scaled up. When the page load is ready we have a JavaScript going through all images and swapping them to a bigger version.

In the old days when we had those 9 different sizes available, it was hardcoded in the script that which size should be used where on the site.

With the cloud service in use we are able to utilize its on-the-fly image manipulations. Now our script actually looks up the size of the containing element of the image (e.g. the parent of the img) and renders an image in exactly that size. This is done simply by changing the size parameters given in the image URL. This enables us to control how large images we are serving just by changing the element size in the stylesheets.

The difference for tablet/mobile when we can select the best possible size for any resolution (click to view bigger version)

Challenges
One of the most challenging things we encountered was the fact that many images are 640x360px in size. That is the original image size! So how to show images that small in articles where we wanted an 880px wide image? We add an upscale effect.

Using the cloud service’s image manipulations, we take the original image, scale it up to the desired size and blur it as much as possible. Let’s call this our canvas. Then we put the original image in its original size on the canvas that we just made. The result is that it looks like our image got blurred borders. The same kind of technique is used on TV when showing old, 4:3 clips in 16:9 format.

We ran into a few bugs in open-source libraries we used. We decided to ditch the custom crop tool and use open-source Jcrop library instead. There was an issue when using a fixed aspect ratio together with a minimum or maximum allowed height of the crop area. We fixed the bug in our GitHub fork and created a pull request to get the fix contributed.

Also when using the cloudinary_php, the PHP library for the cloud service, we noticed a flaw in the logic. When specifying an image to be cropped according to specific coordinates, zero values were not allowed. This prevented any crops to be made e.g. from the top left corner of an image (where both X and Y are 0). The bug was fixed in our fork and merged via our pull request into the library.

Migration
Another challenge was that we had over 160 000 images with a total file size of somewhere around 400GB. For all these, we needed to a) generate a public id, b) upload to the cloud and c) save the image version number, given from the cloud as a response to the upload, in our database.

Of course we had to do this programatically. With a quite simple script we uploaded a sample batch of images. The script read X amount of rows from the database and looped through them, processing one image at the time. The idea was good, but according to our calculations the migration would have taken about 29 days to finish.

We then thought of having multiple instances of the script running simultaneously to speed things up. Again, the idea was good, but we would run into some conflict issues when all the scripts would try to read and write against the same database, let along the same table in the database.

Our final solution was to utilize a message queue for the migration. We chose to use RabbitMQ as our queue, and implemented the Pekkis Queue library as an abstraction layer between the queue and our scripts.

This way we could enqueue all the images to be processed and simultaneously run multiple instances of our script and be sure that each image was processed only once. The migration took all in all about 20 hours.

Written by Rasmus Werling
Rasmus “Rade” Werling has worked with Drupal development for 5 years. He’s speciality’s are backend coding and coming up with creative solutions to problems. He has contributed Drupal modules of his own and loves to take on challenges.

Ny version av IMS på svenska.yle.fi

Efter fem år och 165 000 bilder är det dags att ge IMS (Image management system) som används på svenska.yle.fi ett ansiktslyft. Den nya IMS-versionen har nya funktioner och ett nytt utseende. Om allt går enligt plan tas den i bruk onsdag 26.3.

För alla användare betyder det vissa förändringar, här kommer några skärmdumpar och info om förändringar:

Man öppnar IMS på samma sätt som tidigare
Man öppnar IMS på samma sätt som tidigare. Nu kan man också öppna bilden för redigering genom att klicka på bilden.
Så här ser första vyn ut där man kan välja vad man vill göra
Så här ser första vyn ut där man kan välja vad man vill göra
Bläddra och välj bild
Bläddra och välj bild
Vy man ser då en ny bild har laddats upp
Vy man ser då en ny bild har laddats upp

Om den bild man laddar upp inte är tillräckligt stor varnar systemet om detta. Minimistorlek är 1600×900. Systemet tillåter dock allt som är större än 640×360 px.

Det finns skäl att alltid eftersträva en så stor bild som möjligt. På svenska.yle.fi börjar vi nu använda en bild som är 880×495 px. Om bilden inte uppfyller den storleken kommer vi att förstora den artificiellt. Man kan jämföra med hur man gör med 4:3 bilder som sänds i tv som 16:9.

En annan aspekt är att högupplösta skärmar tas i bruk i allt större utsträckning. Det gör att vi väldigt snart är tvungna att ta i bruk en ännu större storlek fast vår bildbank i IMS inte har tillräckligt stora bilder. Ladda därför alltid upp bilden i största möjliga storlek.

Beskärning går nu att göra i 16:9-, 1:1- och 2:3-format
Beskärning går nu att göra i 16:9-, 1:1- och 2:3-format

Till de bildversioner som besökarna på svenska.yle.fi ser använder vi en automatiskt ansiktsigenkännings-funktion ifall en manuell beskärning saknas, vilket fungerar i 70-90% av fallen. Det ersätter med andra ord inte att en människa beskurit bilden. Då du skall beskära de enskilda formaten klickar du på respektive miniatyrversion (som automatiskt visar en förhandsversion av slutresultatet).

Om beskärningar inte gjorts så ser bilden ut så här för administratorer, så att man skall ha en möjlighet att se att bilden inte är beskärd.
Om beskärningarna saknas ser bilden ut så här för administratörer. Orsaken är att man då ser att bilden behöver beskäras.

Då du väljer en bild skall du alltid kontrollera att beskärningen är korrekt. I föregående version av IMS sparades inte beskärningsdatan eftersom beskärningarna sparades direkt i den enskilda bildfilen. Det ledde till att vi inte kunde återskapa hur bilden varit klippt tidigare. Oberoende av det så behöver en människa kontrollera 1:1- och 2:3-formaten som är helt nya och saknar beskärning.

Detta gör att en okänd procentandel av våra bilder nu är klippta på ett icke kontrollerat sätt (skedde per automatik vid migreringen).

Om du ser en bild som behöver korrigeras kan du öppna den i IMSen genom att gå in och redigera artikeln. Väl inne i artikeln öppnar du den specifika bilden i IMSen genom att klicka på bilden.

De enskilda fälten har fått förklaringar:

För att andra skall hitta din bild lönar det sig att  skriva bra taggar. Separera taggarna med kommatecken,

För att personer som har en synnedsättning också skall veta vad som visas på bilden är ALT-fältet obligatoriskt.

För att personer som har en synnedsättning också skall få veta vad som visas på bilden är ALT fältet obligatoriskt.

Detta fält var tidigare inte obligatoriskt. Om du redigerar en gammal bild blir du därför tvungen att skriva beskrivningen.

Till de nya funktionerna hör:

  • I de situationer som svenska.yle.fi av layoutmässigaskäl behöver veta bildens format och storlek kommer 16:9 formatet att användas
  • Exempel: En bild som du laddar upp kommer alltid att finnas också som 16:9. Om bilden är satt som huvudmedia i en artikel kommer den med nuvarande layout aldrig att visas som 1:1 eller 2:3. 1:1-, original- och 2:3-beskärningen kan du använda inne i en artikels brödtext genom att då du sätter in bilden välja en av dem.
  • Inne i artiklar kan man välja att en bild är 1:1, 16:9, originalformat eller 2:3
  • Inne i artiklar kan man välja att en bild är viktig, den kommer då att visas i ett större format än en bild som är insatt som standard
  • Du kan ladda ner en bild i den storlek som Arenan behöver direkt från IMS
  • Bilderna levereras nu via en CDN (Content Distrubution Network) som gör att bilden levereras snabbare för att den kommer från ett datacenter som är nära användaren
  • Rotera bilden direkt i IMS
  • Bilderna kan visas i vilken pixel-storlek som helst, vilket gör att vi kan skapa bättre användarupplevelser. Vi kan ladda bilder exakt så stora som de på riktigt behöver vara, och användaren behöver inte ladda ner en för tung bild.
  • IMS kan stänga av visningen av alla bilder i svenska.yle.fi om vi av ngn orsak måste minska på hela sajtens vikt. Kan bli aktuellt t.ex. vid en DoS-attack.
  • ”Ersätt bilden”-funktionen beaktar att bildens bredd/höjd kan ha ändrat

De första dagarna kommer bilderna på svenska.yle.fi och admin att vara lite långsammare, men snabbas upp vartefter fler och fler av bilderna har visats och lagras i CDN:ens cache.

Tack till Rasmus och Tero för deras insatser.

Hur många bilder går inte att få i en större storlek?

En av utmaningarna med vår nya design är att bilderna i vårt bildhanteringssystem inte är tillräckligt stora för att passa in i de bredare versionerna av den responsiva designen.

Systemet har funnits så länge att det var ett problem bara att sätta standarden 640×360. Vår rekomendation har varit att man skall ladda upp bilden i originalstorlek till bildhanteringssystemet (IMS).

Igår då jag fick en dump av de storlekar som finns i systemet var det med spänning jag kollade hur väl det gått.

I grafen ovan kan ni se skillnaden mellan bildhanteringssystemet som kanalerna (Svenska) använder jämfört med nyheterna.

Den nya minimistorlek vi behöver är 880px. Det betyder att 31% av nyheternas bilder inte klarar av att fylla utrymmet. För kanalernas del är det 21%. Skillnaden förklaras dels av att kanalerna använder mer pressbilder som är högupplösta.

Ifall vi skulle välja att gå till en ännu större storlek står vi inför situationen att upp till 45 % av bilderna inte uppfyller kraven.

Alternativen vi står inför är:

  • Lägga till svarta kanter på samma sätt som man gjorde övergången till 16:9 i tv-världen – och kan vi då höja minimikravet till 880px för alla nya bilder som laddas in i systemet? Eller behåller vi kravet på 640 och sätter svarta kanter på allt som inte är 880px eller större? Snyggt lär det ju inte bli …
  • Slänga de bilder som inte uppfyller kraven