From de1735495fbfd3981024882e60dd20f27a33b23e Mon Sep 17 00:00:00 2001 From: Timothy Farrell Date: Wed, 3 Jan 2018 17:13:10 -0600 Subject: [PATCH] Add gifs and png support --- .../gallery/src/context/generateThumbnails.js | 35 ++++++--- packages/gallery/src/data/image.js | 77 +++++++++++-------- packages/gallery/src/interface/allImages.js | 2 +- 3 files changed, 72 insertions(+), 42 deletions(-) diff --git a/packages/gallery/src/context/generateThumbnails.js b/packages/gallery/src/context/generateThumbnails.js index b3d27be..000aaa6 100644 --- a/packages/gallery/src/context/generateThumbnails.js +++ b/packages/gallery/src/context/generateThumbnails.js @@ -2,6 +2,8 @@ import pica from 'pica/dist/pica'; import { FileType } from '../data/file.js'; +const THUMBNAIL_MAX_DIMENSION = 320; + export function maxLinearSize(width, height, max) { const ratio = width / height; if (width > height) { @@ -49,16 +51,27 @@ export async function generateThumbnailForImage(doc) { return; } - const attachment = await FileType.getFromURL(doc.sizes.full); - const mimetype = attachment.content_type || attachment.type; - const { width, height } = maxLinearSize(doc.width, doc.height, 320); - const resizedBlob = await resizeImage(attachment, mimetype, width, height); + const { width, height } = maxLinearSize(doc.width, doc.height, THUMBNAIL_MAX_DIMENSION); - const thumbfile = await FileType.upload(resizedBlob); - - await doc.update({ - sizes: { - thumbnail: FileType.getURL(thumbfile) - } - }); + if (width < doc.width && height < doc.height) { + console.log('generating thumbnail'); + // Thumbnail would be smaller + const attachment = await FileType.getFromURL(doc.sizes.full); + const mimetype = attachment.type; + const resizedBlob = await resizeImage(attachment, mimetype, width, height); + const thumbfile = await FileType.upload(resizedBlob); + await doc.update({ + sizes: { + thumbnail: FileType.getURL(thumbfile) + } + }); + } else { + console.log('using original as thumbnail'); + // Thumbnail would be bigger so let's just use the original. + await doc.update({ + sizes: { + thumbnail: doc.sizes.full + } + }); + } } diff --git a/packages/gallery/src/data/image.js b/packages/gallery/src/data/image.js index 7b60ba1..ab7ca32 100644 --- a/packages/gallery/src/data/image.js +++ b/packages/gallery/src/data/image.js @@ -1,7 +1,8 @@ import { PouchDB, TypeSpec } from '../services/db.js'; -import { blobToArrayBuffer } from '../utils/conversion.js'; +import { blobToArrayBuffer, deepAssign } from '../utils/conversion.js'; import { backgroundTask } from '../utils/event.js'; import { FileType } from './file.js'; +import { error } from '../services/console.js'; class ImageSpec extends TypeSpec { static async upload(blob) { @@ -30,7 +31,7 @@ class ImageSpec extends TypeSpec { async delete(cascade = true) { if (cascade) { - Object.keys(this.sizes).forEach(async key => { + new Set(Object.keys(this.sizes)).forEach(async key => { const f = await FileType.getDocFromURL(this.sizes[key]); f.delete(); }); @@ -76,40 +77,56 @@ class ImageSpec extends TypeSpec { } const processImportables = backgroundTask(async function _processImportables(image) { - const { _id, _rev } = image; + const { _id, _rev, sizes, digest } = image; const imageData = await FileType.getFromURL(image.sizes.full); - const ExifParser = await import('exif-parser'); + const img = new Image(); + const imageProps = await new Promise(resolve => { + img.onload = () => { + resolve({ width: img.width, height: img.height }); + URL.revokeObjectURL(img.src); + }; + img.src = URL.createObjectURL(imageData); + }); - const buffer = await blobToArrayBuffer(imageData); + if (new Set(['image/jpg', 'image/jpeg']).has(imageData.type)) { + const ExifParser = await import('exif-parser'); + const buffer = await blobToArrayBuffer(imageData); - const exifData = ExifParser.create(buffer).parse(); - const { tags, imageSize } = exifData; - const { width, height } = imageSize; - const { sizes, digest } = image; - const originalDate = new Date( - tags.DateTimeOriginal ? new Date(tags.DateTimeOriginal * 1000).toISOString() : image.originalDate - ).toISOString(); + try { + const exifData = ExifParser.create(buffer).parse(); + const { tags } = exifData; + const originalDate = new Date( + tags.DateTimeOriginal + ? new Date(tags.DateTimeOriginal * 1000).toISOString() + : image.originalDate + ).toISOString(); + + deepAssign(imageProps, { + originalDate, + width, + height, + orientation: tags.Orientation, + digest, + make: tags.Make, + model: tags.Model, + flash: !!tags.Flash, + iso: tags.ISO, + sizes, + gps: { + latitude: tags.GPSLatitude, + longitude: tags.GPSLongitude, + altitude: tags.GPSAltitude, + heading: tags.GPSImgDirection + } + }); + } catch (e) { + error(e); + } + } delete image.importing; - await image.update({ - originalDate, - width, - height, - orientation: tags.Orientation, - digest, - make: tags.Make, - model: tags.Model, - flash: !!tags.Flash, - iso: tags.ISO, - sizes, - gps: { - latitude: tags.GPSLatitude, - longitude: tags.GPSLongitude, - altitude: tags.GPSAltitude, - heading: tags.GPSImgDirection - } - }); + image.update(imageProps); const module = await import('../context/generateThumbnails'); module.generateThumbnailForImage(image); diff --git a/packages/gallery/src/interface/allImages.js b/packages/gallery/src/interface/allImages.js index 0dffd84..6209bf0 100644 --- a/packages/gallery/src/interface/allImages.js +++ b/packages/gallery/src/interface/allImages.js @@ -90,7 +90,7 @@ export function AllImagesView(vm, params, key, context) { name: 'uploadButton', type: 'file', multiple: true, - accept: '.jpg,.jpeg', // no love for gifs, pngs yet + accept: '.jpg,.jpeg,.png,.gif', onchange: uploadImages, class: injectStyle({ display: 'none' }) })