-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use piexif to dynamically generate density-corrected size images
- Loading branch information
Showing
9 changed files
with
2,595 additions
and
55 deletions.
There are no files selected for viewing
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 |
---|---|---|
|
@@ -2,26 +2,36 @@ | |
<body> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="./resources/piexif.js"></script> | ||
<script src="./resources/exify.js"></script> | ||
<link rel="author" title="Noam Rosenthal" href="[email protected]"> | ||
<img src="resources/exif-resolution-invalid-cm.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-invalid-no-match.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-invalid-partial.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-no-change.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-none.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-hires.jpg" data-width="50" data-height="25" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-lores.jpg" data-width="200" data-height="100" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-non-uniform.jpg" data-width="50" data-height="100" class="test-img" /> | ||
<img src="resources/exif-resolution-with-orientation.jpg" data-width="100" data-height="200" class="test-img" /> | ||
<script> | ||
let run_test = () => { | ||
test(() => { | ||
[...document.querySelectorAll('.test-img')].forEach(img => { | ||
assert_equals(img.naturalWidth, +img.dataset.width, `Density size correction for ${img.src}`); | ||
assert_equals(img.naturalHeight, +img.dataset.height, `Density size correction for ${img.src}`); | ||
}) | ||
}, "Test the image dimensions of different EXIF scenarios"); | ||
async function test_valid(input) { | ||
const image = await createImageWithMetadata(input) | ||
assert_equals(image.naturalWidth, input.preferredWidth) | ||
assert_equals(image.naturalHeight, input.preferredHeight) | ||
} | ||
window.addEventListener("load", run_test); | ||
async function test_invalid(input) { | ||
const image = await createImageWithMetadata(input) | ||
assert_equals(image.naturalWidth, input.width) | ||
assert_equals(image.naturalHeight, input.height) | ||
} | ||
|
||
async function test() { | ||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 2, preferredHeight: 4, resolutionX: 360, resolutionY: 360, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 10, resolutionX: 36, resolutionY: 144, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 10, preferredHeight: 40, resolutionX: 72, resolutionY: 36, resolutionUnit: 2}) | ||
await test_valid({width: 30, height: 30, preferredWidth: 90, preferredHeight: 30, resolutionX: 24, resolutionY: 72, resolutionUnit: 2}) | ||
|
||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2}) | ||
await test_valid({width: 10, height: 20, preferredWidth: 20, preferredHeight: 40, resolutionX: 36, resolutionY: 36, resolutionUnit: 2}) | ||
} | ||
|
||
promise_test(test) | ||
|
||
</script> | ||
|
||
</body> | ||
|
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
77 changes: 42 additions & 35 deletions
77
density-size-correction/density-corrected-size-rendering.html
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 |
---|---|---|
@@ -1,39 +1,46 @@ | ||
<!DOCTYPE html> | ||
<head> | ||
<title>Density corrected size: rendering</title> | ||
<link rel="author" title="Noam Rosenthal" href="[email protected]"> | ||
<link rel="match" href="density-corrected-size-rendering-ref.html" /> | ||
<meta name="assert" content="Assert that images with EXIF density-corrected-size are rendered correctly"> | ||
<script src="./resources/piexif.js"></script> | ||
<script src="./resources/exify.js"></script> | ||
</head> | ||
<body> | ||
<link rel="author" title="Noam Rosenthal" href="[email protected]"> | ||
<link rel="match" href="density-corrected-size-rendering-ref.html" /> | ||
<meta name="assert" content="Assert that images with EXIF density-corrected-size are rendered correctly"> | ||
<img src="resources/exif-resolution-none.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-hires.jpg" data-width="50" data-height="25" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-lores.jpg" data-width="200" data-height="10" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-non-uniform.jpg" data-width="50" data-height="100" class="test-img" /> | ||
<style> | ||
body { | ||
--lores: url(resources/exif-resolution-valid-lores.jpg); | ||
--hires: url(resources/exif-resolution-valid-hires.jpg); | ||
--default: url(resources/exif-resolution-none.jpg); | ||
--non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg); | ||
} | ||
.default-bg {background-image: var(--default); } | ||
.lores-bg {background-image: var(--lores); } | ||
.lores-after::after {content: var(--lores); } | ||
.default-after::after {content: var(--default); } | ||
.hires-bg {background-image: var(--hires); } | ||
.invalid-bg {background-image: var(--invalid); } | ||
.non-uniform-bg {background-image: var(--non-uniform); } | ||
.box { width: 200px; height: 200px; display: inline-block; } | ||
.tiled {background-repeat: repeat; } | ||
.stretch {background-repeat: no-repeat; background-size: contain; } | ||
</style> | ||
<br/> | ||
<div class="default-bg tiled box"></div> | ||
<div class="lores-bg tiled box"></div> | ||
<div class="hires-bg tiled box"></div> | ||
<div class="non-uniform-bg tiled box"></div> | ||
<div class="lores-bg stretch box"></div> | ||
<div class="default-bg stretch box"></div> | ||
<div class="non-uniform-bg stretch box"></div> | ||
<div class="lores-after box"></div> | ||
<div class="default-after box"></div> | ||
<style> | ||
body { | ||
--lores: url(resources/exif-resolution-valid-lores.jpg); | ||
--hires: url(resources/exif-resolution-valid-hires.jpg); | ||
--default: url(resources/exif-resolution-none.jpg); | ||
--non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg); | ||
} | ||
.default-bg {background-image: var(--default); } | ||
.lores-bg {background-image: var(--lores); } | ||
.lores-after::after {content: var(--lores); } | ||
.default-after::after {content: var(--default); } | ||
.hires-bg {background-image: var(--hires); } | ||
.invalid-bg {background-image: var(--invalid); } | ||
.non-uniform-bg {background-image: var(--non-uniform); } | ||
.box { width: 200px; height: 200px; display: inline-block; } | ||
.tiled {background-repeat: repeat; } | ||
.stretch {background-repeat: no-repeat; background-size: contain; } | ||
</style> | ||
<img src="resources/exif-resolution-none.jpg" data-width="100" data-height="50" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-hires.jpg" data-width="50" data-height="25" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-lores.jpg" data-width="200" data-height="10" class="test-img" /> | ||
<img src="resources/exif-resolution-valid-non-uniform.jpg" data-width="50" data-height="100" class="test-img" /> | ||
<br/> | ||
<div class="default-bg tiled box"></div> | ||
<div class="lores-bg tiled box"></div> | ||
<div class="hires-bg tiled box"></div> | ||
<div class="non-uniform-bg tiled box"></div> | ||
<br/> | ||
<div class="lores-bg stretch box"></div> | ||
<div class="default-bg stretch box"></div> | ||
<div class="non-uniform-bg stretch box"></div> | ||
<div class="lores-after box"></div> | ||
<br /> | ||
<div class="default-after box"></div> | ||
</body> | ||
</html> |
4 changes: 2 additions & 2 deletions
4
density-size-correction/density-corrected-various-elements.html
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 |
---|---|---|
@@ -1,9 +1,9 @@ | ||
<html> | ||
<head> | ||
<title>Content-DPR: various elements</title> | ||
<title>Density corrected size: various elements</title> | ||
<link rel="author" title="Noam Rosenthal" href="[email protected]"> | ||
<link rel="match" href="density-corrected-various-elements-ref.html" /> | ||
<meta name="assert" content="Assert that content-dpr is taken into account for images in all relevant elements (input/canvas/svg/video-poster)"> | ||
<meta name="assert" content="Assert that density-corrected size in EXIF is taken into account for images in all relevant elements (input/canvas/svg/video-poster)"> | ||
<style> | ||
.row { | ||
display: flex; | ||
|
Binary file not shown.
Binary file removed
BIN
-1.97 KB
density-size-correction/resources/exif-resolution-invalid-no-match.jpg
Binary file not shown.
Binary file removed
BIN
-1.95 KB
density-size-correction/resources/exif-resolution-invalid-partial.jpg
Binary file not shown.
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,39 @@ | ||
function createImageWithMetadata({ | ||
width, | ||
height, | ||
preferredWidth, | ||
preferredHeight, | ||
resolutionX, | ||
resolutionY, | ||
resolutionUnit, | ||
orientation | ||
}) { | ||
const canvas = document.createElement('canvas') | ||
canvas.width = width || 100 | ||
canvas.height = height || 100 | ||
const ctx = canvas.getContext('2d') | ||
ctx.fillColor = 'green' | ||
ctx.fillRect(0, 0, canvas.width, canvas.height) | ||
const original = canvas.toDataURL('image/jpeg') | ||
const root = {} | ||
const exif = {} | ||
if (orientation !== undefined) | ||
root[piexif.ExifIFD.Orientation] = orientation | ||
if (resolutionX !== undefined) | ||
root[piexif.ImageIFD.XResolution] = [resolutionX, 1] | ||
if (resolutionY !== undefined) | ||
root[piexif.ImageIFD.YResolution] = [resolutionY, 1] | ||
if (resolutionUnit !== undefined) | ||
root[piexif.ImageIFD.ResolutionUnit] = resolutionUnit | ||
if (preferredWidth !== undefined) | ||
exif[piexif.ExifIFD.PixelXDimension] = preferredWidth | ||
if (preferredHeight !== undefined) | ||
exif[piexif.ExifIFD.PixelYDimension] = preferredHeight | ||
const exifString = piexif.dump({'0th': root, 'Exif': exif}) | ||
const newDataUrl = piexif.insert(exifString, original) | ||
const image = new Image() | ||
image.src = newDataUrl | ||
return new Promise(resolve => { | ||
image.onload = () => resolve(image); | ||
}) | ||
} |
Oops, something went wrong.