Skip to content

Commit

Permalink
feat(new tool): HEIC Converter
Browse files Browse the repository at this point in the history
  • Loading branch information
sharevb committed Apr 28, 2024
1 parent 9eac9cb commit 146dd34
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
88 changes: 88 additions & 0 deletions src/tools/heic-converter/heic-converter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<script setup lang="ts">
import { Base64 } from 'js-base64';
import heicConvert from 'heic-convert/browser';
import { useDownloadFileFromBase64Refs } from '@/composable/downloadBase64';
const status = ref<'idle' | 'done' | 'error' | 'processing'>('idle');
const file = ref<File | null>(null);
const base64OutputImage = ref('');
const fileName = ref('');
const format = ref('jpg');
const formats = [
{ value: 'jpg', label: 'JPEG' },
{ value: 'png', label: 'PNG' },
];
const { download } = useDownloadFileFromBase64Refs(
{
source: base64OutputImage,
filename: fileName,
});
async function onFileUploaded(uploadedFile: File) {
file.value = uploadedFile;
const fileBuffer = await uploadedFile.arrayBuffer();
fileName.value = `${uploadedFile.name}${format.value}`;
status.value = 'processing';
try {
let convertFormat;
if (format.value === 'jpg') {
convertFormat = 'JPEG';
}
else if (format.value === 'png') {
convertFormat = 'PNG';
}
else {
throw new Error('unknown format');
}
const outputBuffer = await heicConvert({
buffer: fileBuffer,
format: convertFormat,
quality: 0.98,
});
base64OutputImage.value = `data:image/${convertFormat.toLowerCase()};base64,${Base64.fromUint8Array(outputBuffer)}`;
status.value = 'done';
download();
}
catch (e) {
status.value = 'error';
}
}
</script>

<template>
<div>
<c-select
v-model:value="format"
:options="formats"
label="Output format"
w-100px
/>

<div style="flex: 0 0 100%" mb-3>
<div mx-auto max-w-600px>
<c-file-upload
title="Drag and drop a HEIC file here, or click to select a file"
accept=".heic,.heif" @file-upload="onFileUploaded"
/>
</div>
</div>
<div mt-3 flex justify-center>
<img :src="base64OutputImage" max-w-300px>
</div>

<div mt-3 flex justify-center>
<c-alert v-if="status === 'error'" type="error">
An error occured processing {{ fileName }}. HEIC/HEIF is invalid.
</c-alert>
<n-spin
v-if="status === 'processing'"
size="small"
/>
</div>
</div>
</template>
12 changes: 12 additions & 0 deletions src/tools/heic-converter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArrowsShuffle } from '@vicons/tabler';
import { defineTool } from '../tool';

export const tool = defineTool({
name: 'Heic converter',
path: '/heic-converter',
description: '',
keywords: ['heic', 'converter'],
component: () => import('./heic-converter.vue'),
icon: ArrowsShuffle,
createdAt: new Date('2024-04-23'),
});
2 changes: 2 additions & 0 deletions src/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { tool as asciiTextDrawer } from './ascii-text-drawer';

import { tool as textToUnicode } from './text-to-unicode';
import { tool as safelinkDecoder } from './safelink-decoder';
import { tool as heicConverter } from './heic-converter';
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
import { tool as numeronymGenerator } from './numeronym-generator';
import { tool as macAddressGenerator } from './mac-address-generator';
Expand Down Expand Up @@ -133,6 +134,7 @@ export const toolsByCategory: ToolCategory[] = [
{
name: 'Images and videos',
components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder],
heicConverter,
},
{
name: 'Development',
Expand Down

0 comments on commit 146dd34

Please sign in to comment.