convert from HEIC in browser (temporary)

This commit is contained in:
Will Freeman
2024-11-13 23:33:22 -07:00
parent 09a6e6f9ad
commit 9b8c92a042
3 changed files with 46 additions and 3 deletions

View File

@@ -11,6 +11,7 @@
"@auth0/auth0-vue": "^2.3.3",
"axios": "^1.7.7",
"exifreader": "^4.25.0",
"heic2any": "^0.0.4",
"vue": "^3.4.29",
"vue-router": "^4.3.3",
"vuetify": "^3.7.2"
@@ -1113,6 +1114,11 @@
"he": "bin/he"
}
},
"node_modules/heic2any": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/heic2any/-/heic2any-0.0.4.tgz",
"integrity": "sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA=="
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2258,6 +2264,11 @@
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"heic2any": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/heic2any/-/heic2any-0.0.4.tgz",
"integrity": "sha512-3lLnZiDELfabVH87htnRolZ2iehX9zwpRyGNz22GKXIu0fznlblf0/ftppXKNqS26dqFSeqfIBhAmAj/uSp0cA=="
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",

View File

@@ -14,6 +14,7 @@
"@auth0/auth0-vue": "^2.3.3",
"axios": "^1.7.7",
"exifreader": "^4.25.0",
"heic2any": "^0.0.4",
"vue": "^3.4.29",
"vue-router": "^4.3.3",
"vuetify": "^3.7.2"

View File

@@ -6,7 +6,13 @@
<v-row class="align-center">
<v-col cols="12" sm="6">
<v-img cover ref="imageEl" :src="submission.publicUrl" @load="loadExif" />
<v-card flat v-if="isConverting">
<v-card-title>Converting from HEIC</v-card-title>
<v-card-text>
<v-progress-linear indeterminate color="primary"></v-progress-linear>
</v-card-text>
</v-card>
<v-img v-else cover ref="imageEl" :src="imageSrc"/>
</v-col>
<v-col cols="12" sm="6">
@@ -45,14 +51,20 @@
<script setup lang="ts">
import type { PropType, Ref } from 'vue';
import { computed, defineProps, ref, defineEmits } from 'vue';
import { computed, defineProps, ref, defineEmits, onMounted } from 'vue';
import type { Submission } from '@/types';
import ExifReader from 'exifreader';
import heic2any from "heic2any";
const emit = defineEmits(['cancel', 'delete']);
const lat: Ref<number|null> = ref(null);
const lng: Ref<number|null> = ref(null);
const isHeic = computed(() => props.submission.objectKey.endsWith('.heic'));
const pngSrc: Ref<string|undefined> = ref(undefined);
const isConverting = computed(() => isHeic.value && !pngSrc.value);
const imageSrc = computed(() => isHeic.value ? pngSrc.value : props.submission.publicUrl);
const showInstructions = ref(false);
@@ -64,11 +76,30 @@ function deleteSubmission() {
emit('delete', props.submission);
}
const loadExif = async (e: any) => {
onMounted(() => {
loadExif()
});
const loadExif = async () => {
const response = await fetch(props.submission.publicUrl);
const arrayBuffer = await response.arrayBuffer();
const tags = ExifReader.load(arrayBuffer);
if (isHeic.value) {
console.log('Converting HEIC to PNG');
heic2any({
blob: new Blob([arrayBuffer], { type: 'image/heic' }),
}).then((result: Blob | Blob[]) => {
if (Array.isArray(result)) {
pngSrc.value = URL.createObjectURL(result[0]);
} else {
pngSrc.value = URL.createObjectURL(result);
}
});
} else {
console.log('Image is not HEIC');
}
if (tags.GPSLatitude && tags.GPSLongitude) {
lat.value = parseFloat(tags.GPSLatitude.description);
lng.value = parseFloat(tags.GPSLongitude.description);