-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #92 from edgio-docs/COMSUP-163_image_opt
[COMSUP-163] Image optimization
- Loading branch information
Showing
9 changed files
with
25,537 additions
and
0 deletions.
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
examples/v7-image-optimization/.github/pull_request_template.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
**NOTICE TO CONTRIBUTORS** | ||
|
||
This repository is not actively monitored and any pull requests made to this repository will be closed/ignored. | ||
|
||
Please submit the pull request to [edgio-docs/edgio-examples](https://github.com/edgio-docs/edgio-examples) instead. |
18 changes: 18 additions & 0 deletions
18
examples/v7-image-optimization/.github/workflows/edgio.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
name: Deploy to Edgio | ||
|
||
on: | ||
workflow_dispatch: | ||
push: | ||
|
||
jobs: | ||
deploy-to-edgio: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16 | ||
- run: if [ -f yarn.lock ]; then yarn install; else npm ci; fi | ||
- run: if [ -f yarn.lock ]; then yarn edgio:deploy -- --token=$EDGIO_DEPLOY_TOKEN; else npm run edgio:deploy -- --token=$EDGIO_DEPLOY_TOKEN; fi | ||
env: | ||
EDGIO_DEPLOY_TOKEN: ${{secrets.EDGIO_DEPLOY_TOKEN}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Edgio generated build directory | ||
/.edgio | ||
|
||
/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// This file was automatically added by edgio init. | ||
// You should commit this file to source control. | ||
// Learn more about this file at https://docs.edg.io/guides/edgio_config | ||
module.exports = { | ||
// The name of the site in Edgio to which this app should be deployed. | ||
name: 'edgio-v7-image-optimization-example', | ||
|
||
origins: [ | ||
{ | ||
name: 'wiki', | ||
override_host_header: 'en.wikipedia.org', | ||
hosts: [ | ||
{ | ||
location: 'en.wikipedia.org', | ||
}, | ||
], | ||
tls_verify: { | ||
use_sni: true, | ||
allow_self_signed_certs: true, | ||
sni_hint_and_strict_san_check: 'en.wikipedia.org', | ||
}, | ||
}, | ||
{ | ||
name: 'wikiupload', | ||
override_host_header: 'upload.wikimedia.org', | ||
hosts: [ | ||
{ | ||
location: 'upload.wikimedia.org', | ||
}, | ||
], | ||
tls_verify: { | ||
use_sni: true, | ||
allow_self_signed_certs: true, | ||
sni_hint_and_strict_san_check: 'upload.wikimedia.org', | ||
}, | ||
}, | ||
], | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import * as cheerio from 'cheerio'; | ||
import urlParse from 'url-parse'; | ||
import fetch from 'node-fetch'; | ||
|
||
export default async function (req, res) { | ||
const resp = await fetch('https://en.wikipedia.org'); | ||
const html = await resp.text(); | ||
const $ = cheerio.load(html); | ||
|
||
const wikimediaImages = []; | ||
$('img').each((index, element) => { | ||
const src = $(element).attr('src'); | ||
if (src.includes('wikimedia') && wikimediaImages.length < 5) { | ||
const url = urlParse(`https:${src}`); | ||
const { pathname } = url; | ||
wikimediaImages.push(pathname); | ||
} | ||
}); | ||
|
||
const imageCards = generateImageCards(wikimediaImages); | ||
const newHtml = createHtml(imageCards); | ||
|
||
res.setHeader('Content-Type', 'text/html'); | ||
res.body = newHtml; | ||
} | ||
|
||
const optimizations = [ | ||
{ | ||
optimization: 'format=webp', | ||
description: 'Optimized to WebP format', | ||
}, | ||
{ | ||
optimization: 'pad=45&bg-color=000000', | ||
description: 'Padded with black background', | ||
}, | ||
{ | ||
optimization: 'rotate=90&height=262', | ||
description: 'Rotated 90 degrees and resized', | ||
}, | ||
{ | ||
optimization: 'quality=5', | ||
description: 'Quality Adjusted to 5%', | ||
}, | ||
{ | ||
optimization: 'blur=20', | ||
description: 'Blur Filter Applied', | ||
}, | ||
{ | ||
optimization: 'width=200&height=200', | ||
description: 'Resized to 200x200', | ||
}, | ||
]; | ||
|
||
const generateImageCards = (wikimediaImages) => { | ||
const demoImageCards = optimizations | ||
.map( | ||
({ optimization, description }) => ` | ||
<div class="image-card"> | ||
<img src="/images/demo.jpg?${optimization}" alt="${description}"> | ||
<div class="info"> | ||
<p>${description} using: <pre><code>?${optimization}</code></pre></p> | ||
</div> | ||
</div> | ||
` | ||
) | ||
.join(''); | ||
|
||
const wikimediaImageCards = wikimediaImages | ||
.map((src, index) => { | ||
const { optimization, description } = | ||
optimizations[index % optimizations.length]; | ||
return ` | ||
<div class="image-card"> | ||
<img src="/img-optimize${src}?${optimization}" alt="${description}"> | ||
<div class="info"> | ||
<p>${description} using: <pre><code>?${optimization}</code></pre></p> | ||
</div> | ||
</div> | ||
`; | ||
}) | ||
.join(''); | ||
|
||
return { demoImageCards, wikimediaImageCards }; | ||
}; | ||
|
||
const createHtml = ({ demoImageCards, wikimediaImageCards }) => ` | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>Image Showcase</title> | ||
<style> | ||
body { | ||
font-family: Arial, sans-serif; | ||
background-color: #f0f0f0; | ||
margin: 0; | ||
padding: 0; | ||
} | ||
.container { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
padding: 16px; | ||
} | ||
.section { | ||
width: 100%; | ||
max-width: 1200px; /* Adjust this value to your preference */ | ||
margin-bottom: 32px; | ||
} | ||
.section h2, .section p { | ||
margin-bottom: 16px; | ||
text-align: center; /* Center aligns the section headers */ | ||
} | ||
.image-set { | ||
display: flex; | ||
flex-wrap: wrap; | ||
gap: 16px; | ||
justify-content: center; /* Centers the image cards within the image-set */ | ||
text-align: center; /* Center aligns text within the image cards */ | ||
} | ||
.image-card { | ||
background-color: #fff; | ||
border: 1px solid #ddd; | ||
border-radius: 8px; | ||
overflow: hidden; | ||
transition: transform 0.3s; | ||
flex: 1 1 calc(33.333% - 16px); | ||
max-width: calc(33.333% - 16px); | ||
} | ||
.image-card:hover { | ||
transform: scale(1.05); | ||
} | ||
.image-card img { | ||
display: block; | ||
max-width: 100%; | ||
border-bottom: 1px solid #ddd; | ||
margin: 0 auto; /* Centers images within the image cards */ | ||
} | ||
.image-card .info { | ||
padding: 16px; | ||
} | ||
@media (max-width: 768px) { | ||
.image-card { | ||
flex: 1 1 calc(50% - 16px); | ||
max-width: calc(50% - 16px); | ||
} | ||
} | ||
@media (max-width: 480px) { | ||
.image-card { | ||
flex: 1 1 100%; | ||
max-width: 100%; | ||
} | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<div class="section"> | ||
<h2>Optimized Local Static Images</h2> | ||
<p>This image is bundled as part of the project, served from an Edgio static asset origin, and processed by the image optimizer.</p> | ||
<div class="image-set"> | ||
${demoImageCards} | ||
</div> | ||
</div> | ||
<div class="section"> | ||
<h2>Optimized Remote Images</h2> | ||
<p>These images are fetched from Wikipedia, proxied through Edgio and processed by the image optimizer.</p> | ||
<div class="image-set"> | ||
${wikimediaImageCards} | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
</html> | ||
`; |
Oops, something went wrong.