Add support for AVIF covers, and multiple image source sets in covers

This commit is contained in:
Alex Cabal 2020-08-06 17:03:39 -05:00
parent 958b047f64
commit 1ab7c8c0fe
8 changed files with 56 additions and 12 deletions

View file

@ -210,7 +210,7 @@ Define domain standardebooks.org
# Redirect cover images with caching sha's to the root image # Redirect cover images with caching sha's to the root image
# We do this because some sites like Google cache the cover image path, so changing it results in lots of 404s # We do this because some sites like Google cache the cover image path, so changing it results in lots of 404s
RewriteRule ^/images/covers/(.+?)\-[a-z0-9]{8}\-(cover|hero)(@2x)?\.jpg$ /images/covers/$1-$2$3.jpg RewriteRule ^/images/covers/(.+?)\-[a-z0-9]{8}\-(cover|hero)(@2x)?\.(jpg|avif)$ /images/covers/$1-$2$3.$4
RewriteRule ^/ebooks/([^\./]+?)$ /ebooks/author.php?url-path=$1 [QSA] RewriteRule ^/ebooks/([^\./]+?)$ /ebooks/author.php?url-path=$1 [QSA]
RewriteRule ^/tags/([^\./]+?)$ /ebooks/index.php?tag=$1 [QSA] RewriteRule ^/tags/([^\./]+?)$ /ebooks/index.php?tag=$1 [QSA]

View file

@ -209,7 +209,7 @@ Define domain standardebooks.test
# Redirect cover images with caching sha's to the root image # Redirect cover images with caching sha's to the root image
# We do this because some sites like Google cache the cover image path, so changing it results in lots of 404s # We do this because some sites like Google cache the cover image path, so changing it results in lots of 404s
RewriteRule ^/images/covers/(.+?)\-[a-z0-9]{8}\-(cover|hero)(@2x)?\.jpg$ /images/covers/$1-$2$3.jpg RewriteRule ^/images/covers/(.+?)\-[a-z0-9]{8}\-(cover|hero)(@2x)?\.(jpg|avif)$ /images/covers/$1-$2$3.$4
RewriteRule ^/ebooks/([^\./]+?)$ /ebooks/author.php?url-path=$1 [QSA] RewriteRule ^/ebooks/([^\./]+?)$ /ebooks/author.php?url-path=$1 [QSA]
RewriteRule ^/tags/([^\./]+?)$ /ebooks/index.php?tag=$1 [QSA] RewriteRule ^/tags/([^\./]+?)$ /ebooks/index.php?tag=$1 [QSA]

View file

@ -24,9 +24,13 @@ class Ebook{
public $Identifier; public $Identifier;
public $UrlSafeIdentifier; public $UrlSafeIdentifier;
public $HeroImageUrl; public $HeroImageUrl;
public $HeroImageAvifUrl;
public $HeroImage2xUrl; public $HeroImage2xUrl;
public $HeroImage2xAvifUrl;
public $CoverImageUrl; public $CoverImageUrl;
public $CoverImageAvifUrl;
public $CoverImage2xUrl; public $CoverImage2xUrl;
public $CoverImage2xAvifUrl;
public $DistCoverUrl; public $DistCoverUrl;
public $Title; public $Title;
public $FullTitle; public $FullTitle;
@ -139,9 +143,13 @@ class Ebook{
} }
$hash = substr(sha1($this->GitCommits[0]->Timestamp->format('U') . ' ' . $this->GitCommits[0]->Message), 0, 8); $hash = substr(sha1($this->GitCommits[0]->Timestamp->format('U') . ' ' . $this->GitCommits[0]->Message), 0, 8);
$this->CoverImageUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover.jpg'; $this->CoverImageUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover.jpg';
$this->CoverImageAvifUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover.avif';
$this->CoverImage2xUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover@2x.jpg'; $this->CoverImage2xUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover@2x.jpg';
$this->CoverImage2xAvifUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-cover@2x.avif';
$this->HeroImageUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero.jpg'; $this->HeroImageUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero.jpg';
$this->HeroImageAvifUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero.avif';
$this->HeroImage2xUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero@2x.jpg'; $this->HeroImage2xUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero@2x.jpg';
$this->HeroImage2xAvifUrl = '/images/covers/' . $this->UrlSafeIdentifier . '-' . $hash . '-hero@2x.avif';
// Now do some heavy XML lifting! // Now do some heavy XML lifting!
$xml = new SimpleXMLElement(str_replace('xmlns=', 'ns=', $rawMetadata)); $xml = new SimpleXMLElement(str_replace('xmlns=', 'ns=', $rawMetadata));

View file

@ -69,6 +69,8 @@ require "git" "Try: apt-get install git"
require "php" "Try: apt-get install php-cli" require "php" "Try: apt-get install php-cli"
require "se" "Read: https://standardebooks.org/tools" require "se" "Read: https://standardebooks.org/tools"
# go-avif is compiled from https://github.com/Kagami/go-avif/
scriptsDir="$(dirname "$(readlink -f "$0")")" scriptsDir="$(dirname "$(readlink -f "$0")")"
if ! [ -x "${scriptsDir}"/reset-php-fpm-opcache ]; then if ! [ -x "${scriptsDir}"/reset-php-fpm-opcache ]; then
@ -136,8 +138,11 @@ do
git show HEAD:images/cover.jpg > "${imgWorkDir}/${urlSafeIdentifier}.jpg" git show HEAD:images/cover.jpg > "${imgWorkDir}/${urlSafeIdentifier}.jpg"
cp "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" cp "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg"
# Resize and crop the image to 2156 width, 720 height, and starting at the coords 0,1078 # Resize and crop the image to 2156 width, 720 height, and starting at the coords 0,1078
convert -resize "1078" -crop "1078x359+0+539" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero.jpg" convert -resize "1078" -crop "1078x359+0+539" -sampling-factor 4:2:0 -strip -quality 100 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero.jpg"
convert -resize "2156" -crop "2156x718+0+1078" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero@2x.jpg" convert -resize "2156" -crop "2156x718+0+1078" -sampling-factor 4:2:0 -strip -quality 100 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-hero@2x.jpg"
"${scriptsDir}"/go-avif -e "${imgWorkDir}/${urlSafeIdentifier}-hero.jpg" -o "${imgWorkDir}/${urlSafeIdentifier}-hero.avif" --best
"${scriptsDir}"/go-avif -e "${imgWorkDir}/${urlSafeIdentifier}-hero@2x.jpg" -o "${imgWorkDir}/${urlSafeIdentifier}-hero@2x.avif" --best
# Build the cover image thumbnail # Build the cover image thumbnail
# We use JPG instead of SVG for several reasons: # We use JPG instead of SVG for several reasons:
@ -158,9 +163,15 @@ do
convert -resize "196" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.png" "${imgWorkDir}/${urlSafeIdentifier}.jpg" convert -resize "196" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}.png" "${imgWorkDir}/${urlSafeIdentifier}.jpg"
convert -resize "392" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.png" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" convert -resize "392" -sampling-factor 4:2:0 -strip -quality 75 -colorspace RGB -interlace JPEG "${imgWorkDir}/${urlSafeIdentifier}@2x.png" "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg"
"${scriptsDir}"/go-avif -e "${imgWorkDir}/${urlSafeIdentifier}.jpg" -o "${imgWorkDir}/${urlSafeIdentifier}.avif" --best
"${scriptsDir}"/go-avif -e "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" -o "${imgWorkDir}/${urlSafeIdentifier}@2x.avif" --best
mv "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover@2x.jpg" mv "${imgWorkDir}/${urlSafeIdentifier}@2x.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover@2x.jpg"
mv "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover.jpg" mv "${imgWorkDir}/${urlSafeIdentifier}.jpg" "${imgWorkDir}/${urlSafeIdentifier}-cover.jpg"
mv "${imgWorkDir}/${urlSafeIdentifier}@2x.avif" "${imgWorkDir}/${urlSafeIdentifier}-cover@2x.avif"
mv "${imgWorkDir}/${urlSafeIdentifier}.avif" "${imgWorkDir}/${urlSafeIdentifier}-cover.avif"
sudo chgrp --preserve-root --recursive "${group}" "${imgWorkDir}/${urlSafeIdentifier}"* sudo chgrp --preserve-root --recursive "${group}" "${imgWorkDir}/${urlSafeIdentifier}"*
sudo chmod --preserve-root --recursive g+w "${imgWorkDir}/${urlSafeIdentifier}"* sudo chmod --preserve-root --recursive g+w "${imgWorkDir}/${urlSafeIdentifier}"*
@ -198,7 +209,7 @@ do
mv "${workDir}"/* "${webDir}/" mv "${workDir}"/* "${webDir}/"
# Move the cover images over # Move the cover images over
mv "${imgWorkDir}/${urlSafeIdentifier}"*.jpg "${webRoot}/www/images/covers/" mv "${imgWorkDir}/${urlSafeIdentifier}"*.{jpg,avif} "${webRoot}/www/images/covers/"
# Delete the now-empty work dir (empty except for .git) # Delete the now-empty work dir (empty except for .git)
rm --preserve-root --recursive --force "${workDir}" "${imgWorkDir}" rm --preserve-root --recursive --force "${workDir}" "${imgWorkDir}"

BIN
scripts/go-avif Executable file

Binary file not shown.

View file

@ -6,7 +6,13 @@ if(!isset($ebooks)){
<ol> <ol>
<? foreach($ebooks as $ebook){ ?> <? foreach($ebooks as $ebook){ ?>
<li> <li>
<a href="<?= $ebook->Url ?>"><img src="<?= $ebook->CoverImage2xUrl ?>" title="<?= Formatter::ToPlainText($ebook->Title) ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText($ebook->Title) ?>" /></a> <a href="<?= $ebook->Url ?>">
<picture>
<source srcset="<?= $ebook->CoverImage2xAvifUrl ?> 2x, <?= $ebook->CoverImageAvifUrl ?> 1x" type="image/avif">
<source srcset="<?= $ebook->CoverImage2xUrl ?> 2x, <?= $ebook->CoverImageUrl ?> 1x" type="image/jpg">
<img src="<?= $ebook->CoverImage2xUrl ?>" title="<?= Formatter::ToPlainText($ebook->Title) ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($ebook->TitleWithCreditsHtml)) ?>" />
</picture>
</a>
<p><a href="<?= $ebook->Url ?>"><?= Formatter::ToPlainText($ebook->Title) ?></a></p> <p><a href="<?= $ebook->Url ?>"><?= Formatter::ToPlainText($ebook->Title) ?></a></p>
<? foreach($ebook->Authors as $author){ ?> <? foreach($ebook->Authors as $author){ ?>
<p class="author"><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a></p> <p class="author"><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a></p>

View file

@ -687,8 +687,7 @@ article.ebook > header > div a:visited{
text-decoration: none; text-decoration: none;
} }
article.ebook > header > img{ article.ebook > header img{
width: 100%;
top: 0; top: 0;
left: 0; left: 0;
position: absolute; position: absolute;

View file

@ -44,10 +44,18 @@ try{
$ebooks = Library::GetEbooks(); $ebooks = Library::GetEbooks();
shuffle($ebooks); shuffle($ebooks);
for($i = 0; $i < 5; $i++){ $targetCarouselSize = 5;
if(isset($ebooks[$i])){ if(sizeof($ebooks) < $targetCarouselSize){
$targetCarouselSize = sizeof($ebooks);
}
$i = 0;
while(sizeof($carousel) < $targetCarouselSize){
if(isset($ebooks[$i]) && $ebooks[$i]->Url !== $ebook->Url){
$carousel[] = $ebooks[$i]; $carousel[] = $ebooks[$i];
} }
$i++;
} }
} }
catch(SeeOtherEbookException $ex){ catch(SeeOtherEbookException $ex){
@ -70,7 +78,11 @@ catch(\Exception $ex){
<p><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a></p> <p><a href="<?= Formatter::ToPlainText($ebook->AuthorsUrl) ?>"><?= Formatter::ToPlainText($author->Name) ?></a></p>
<? } ?> <? } ?>
</div> </div>
<img src="<?= $ebook->HeroImage2xUrl ?>" alt="The cover for the Standard Ebooks edition of <?= $ebook->Title ?>." /> <picture>
<source srcset="<?= $ebook->HeroImage2xAvifUrl ?> 2x, <?= $ebook->HeroImageAvifUrl ?> 1x" type="image/avif">
<source srcset="<?= $ebook->HeroImage2xUrl ?> 2x, <?= $ebook->HeroImageUrl ?> 1x" type="image/jpg">
<img src="<?= $ebook->HeroImage2xUrl ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($ebook->TitleWithCreditsHtml)) ?>">
</picture>
</header> </header>
<aside id="reading-ease"> <aside id="reading-ease">
@ -187,7 +199,15 @@ catch(\Exception $ex){
<h2>More free ebooks</h2> <h2>More free ebooks</h2>
<ul> <ul>
<? foreach($carousel as $carouselEbook){ ?> <? foreach($carousel as $carouselEbook){ ?>
<li><a href="<?= $carouselEbook->Url ?>"><img src="<?= $carouselEbook->CoverImage2xUrl ?>"<? /* srcset="<?= $carouselEbook->CoverImage2xUrl ?> 2x, <?= $carouselEbook->CoverImageUrl ?> 1x" */ ?> alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText($carouselEbook->Title) ?>" title="<?= Formatter::ToPlainText($carouselEbook->Title) ?>" /></a></li> <li>
<a href="<?= $carouselEbook->Url ?>">
<picture>
<source srcset="<?= $carouselEbook->CoverImage2xAvifUrl ?> 2x, <?= $carouselEbook->CoverImageAvifUrl ?> 1x" type="image/avif">
<source srcset="<?= $carouselEbook->CoverImage2xUrl ?> 2x, <?= $carouselEbook->CoverImageUrl ?> 1x" type="image/jpg">
<img src="<?= $carouselEbook->HeroImage2xUrl ?>" alt="The cover for the Standard Ebooks edition of <?= Formatter::ToPlainText(strip_tags($carouselEbook->TitleWithCreditsHtml)) ?>">
</picture>
</a>
</li>
<? } ?> <? } ?>
</ul> </ul>
</aside> </aside>