mirror of
https://github.com/CorentinTh/it-tools.git
synced 2025-05-04 05:19:12 -04:00
parent
e1b4f9aafe
commit
ba1b5bc5b6
8 changed files with 802 additions and 65 deletions
1
components.d.ts
vendored
1
components.d.ts
vendored
|
@ -154,6 +154,7 @@ declare module '@vue/runtime-core' {
|
|||
PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default']
|
||||
QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default']
|
||||
RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default']
|
||||
RemoveExif: typeof import('./src/tools/remove-exif/remove-exif.vue')['default']
|
||||
ResultRow: typeof import('./src/tools/ipv4-range-expander/result-row.vue')['default']
|
||||
RomanNumeralConverter: typeof import('./src/tools/roman-numeral-converter/roman-numeral-converter.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
"@tiptap/starter-kit": "2.1.6",
|
||||
"@tiptap/vue-3": "2.0.3",
|
||||
"@types/figlet": "^1.5.8",
|
||||
"@types/memorystream": "^0.3.4",
|
||||
"@vicons/material": "^0.12.0",
|
||||
"@vicons/tabler": "^0.12.0",
|
||||
"@vueuse/core": "^10.3.0",
|
||||
|
@ -58,6 +59,7 @@
|
|||
"date-fns": "^2.29.3",
|
||||
"dompurify": "^3.0.6",
|
||||
"emojilib": "^3.0.10",
|
||||
"exif-be-gone": "^1.5.1",
|
||||
"figlet": "^1.7.0",
|
||||
"figue": "^1.2.0",
|
||||
"fuse.js": "^6.6.2",
|
||||
|
@ -71,6 +73,7 @@
|
|||
"lodash": "^4.17.21",
|
||||
"marked": "^10.0.0",
|
||||
"mathjs": "^11.9.1",
|
||||
"memorystream": "^0.3.1",
|
||||
"mime-types": "^2.1.35",
|
||||
"monaco-editor": "^0.43.0",
|
||||
"naive-ui": "^2.35.0",
|
||||
|
@ -132,6 +135,7 @@
|
|||
"unplugin-icons": "^0.17.0",
|
||||
"unplugin-vue-components": "^0.25.0",
|
||||
"vite": "^4.4.9",
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"vite-plugin-pwa": "^0.16.0",
|
||||
"vite-plugin-vue-markdown": "^0.23.5",
|
||||
"vite-svg-loader": "^4.0.0",
|
||||
|
|
744
pnpm-lock.yaml
generated
744
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
|||
import { extension as getExtensionFromMimeType, extension as getMimeTypeFromExtension } from 'mime-types';
|
||||
import type { Ref } from 'vue';
|
||||
import type { MaybeRef, Ref } from 'vue';
|
||||
import _ from 'lodash';
|
||||
import { get } from '@vueuse/core';
|
||||
|
||||
export {
|
||||
getMimeTypeFromBase64,
|
||||
|
@ -75,21 +76,11 @@ function downloadFromBase64({ sourceValue, filename, extension, fileMimeType }:
|
|||
}
|
||||
|
||||
function useDownloadFileFromBase64(
|
||||
{ source, filename, extension, fileMimeType }:
|
||||
{ source: Ref<string>; filename?: string; extension?: string; fileMimeType?: string }) {
|
||||
return {
|
||||
download() {
|
||||
downloadFromBase64({ sourceValue: source.value, filename, extension, fileMimeType });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function useDownloadFileFromBase64Refs(
|
||||
{ source, filename, extension }:
|
||||
{ source: Ref<string>; filename?: Ref<string>; extension?: Ref<string> }) {
|
||||
{ source: MaybeRef<string>; filename?: MaybeRef<string>; extension?: MaybeRef<string> }) {
|
||||
return {
|
||||
download() {
|
||||
downloadFromBase64({ sourceValue: source.value, filename: filename?.value, extension: extension?.value });
|
||||
downloadFromBase64({ sourceValue: get(source), filename: get(filename), extension: get(extension) });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -116,3 +107,13 @@ function previewImageFromBase64(base64String: string): HTMLImageElement {
|
|||
|
||||
return img;
|
||||
}
|
||||
|
||||
function useDownloadFileFromBase64Refs(
|
||||
{ source, filename, extension }:
|
||||
{ source: Ref<string>; filename?: Ref<string>; extension?: Ref<string> }) {
|
||||
return {
|
||||
download() {
|
||||
downloadFromBase64({ sourceValue: source.value, filename: filename?.value, extension: extension?.value });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 removeExif } from './remove-exif';
|
||||
import { tool as pdfSignatureChecker } from './pdf-signature-checker';
|
||||
import { tool as numeronymGenerator } from './numeronym-generator';
|
||||
import { tool as macAddressGenerator } from './mac-address-generator';
|
||||
|
@ -132,7 +133,13 @@ export const toolsByCategory: ToolCategory[] = [
|
|||
},
|
||||
{
|
||||
name: 'Images and videos',
|
||||
components: [qrCodeGenerator, wifiQrCodeGenerator, svgPlaceholderGenerator, cameraRecorder],
|
||||
components: [
|
||||
qrCodeGenerator,
|
||||
wifiQrCodeGenerator,
|
||||
svgPlaceholderGenerator,
|
||||
cameraRecorder,
|
||||
removeExif,
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Development',
|
||||
|
|
12
src/tools/remove-exif/index.ts
Normal file
12
src/tools/remove-exif/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { PictureInPictureOff } from '@vicons/tabler';
|
||||
import { defineTool } from '../tool';
|
||||
|
||||
export const tool = defineTool({
|
||||
name: 'Remove EXIF',
|
||||
path: '/remove-exif',
|
||||
description: 'Remove Exif from JPEG Files',
|
||||
keywords: ['remove', 'exif', 'jpeg'],
|
||||
component: () => import('./remove-exif.vue'),
|
||||
icon: PictureInPictureOff,
|
||||
createdAt: new Date('2024-07-14'),
|
||||
});
|
68
src/tools/remove-exif/remove-exif.vue
Normal file
68
src/tools/remove-exif/remove-exif.vue
Normal file
|
@ -0,0 +1,68 @@
|
|||
<script setup lang="ts">
|
||||
import { Buffer } from 'node:buffer';
|
||||
import { Base64 } from 'js-base64';
|
||||
import ExifTransformer from 'exif-be-gone';
|
||||
import MemoryStream from 'memorystream';
|
||||
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
|
||||
|
||||
const status = ref<'idle' | 'done' | 'error' | 'processing'>('idle');
|
||||
const file = ref<File | null>(null);
|
||||
|
||||
interface ToBufferMemoryStream extends MemoryStream {
|
||||
toBuffer(): Buffer
|
||||
}
|
||||
|
||||
const base64OutputFile = ref('');
|
||||
const fileName = ref('');
|
||||
const { download } = useDownloadFileFromBase64(
|
||||
{
|
||||
source: base64OutputFile,
|
||||
filename: fileName,
|
||||
extension: 'jpg',
|
||||
});
|
||||
|
||||
async function onFileUploaded(uploadedFile: File) {
|
||||
file.value = uploadedFile;
|
||||
const fileBuffer = await uploadedFile.arrayBuffer();
|
||||
|
||||
fileName.value = `noexif_${uploadedFile.name}`;
|
||||
status.value = 'processing';
|
||||
try {
|
||||
const inStream = MemoryStream.createReadStream(Buffer.from(fileBuffer));
|
||||
const outStream = MemoryStream.createWriteStream();
|
||||
const trans = new ExifTransformer();
|
||||
await new Promise((resolve, _reject) => {
|
||||
inStream.pipe(trans).pipe(outStream).on('finish', () => resolve(true));
|
||||
});
|
||||
|
||||
const outFileBuffer = (outStream as ToBufferMemoryStream).toBuffer();
|
||||
base64OutputFile.value = `data:image/File;base64,${Base64.fromUint8Array(outFileBuffer)}`;
|
||||
status.value = 'done';
|
||||
|
||||
download();
|
||||
}
|
||||
catch (e) {
|
||||
status.value = 'error';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div style="flex: 0 0 100%">
|
||||
<div mx-auto max-w-600px>
|
||||
<c-file-upload title="Drag and drop a Image file here, or click to select a file" accept="image/*" @file-upload="onFileUploaded" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div mt-3 flex justify-center>
|
||||
<c-alert v-if="status === 'error'" type="error">
|
||||
An error occured processing {{ fileName }}
|
||||
</c-alert>
|
||||
<n-spin
|
||||
v-if="status === 'processing'"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
|
@ -15,6 +15,7 @@ import { VitePWA } from 'vite-plugin-pwa';
|
|||
import markdown from 'vite-plugin-vue-markdown';
|
||||
import svgLoader from 'vite-svg-loader';
|
||||
import { configDefaults } from 'vitest/config';
|
||||
import { nodePolyfills } from 'vite-plugin-node-polyfills'
|
||||
|
||||
const baseUrl = process.env.BASE_URL ?? '/';
|
||||
|
||||
|
@ -97,6 +98,7 @@ export default defineConfig({
|
|||
resolvers: [NaiveUiResolver(), IconsResolver({ prefix: 'icon' })],
|
||||
}),
|
||||
Unocss(),
|
||||
nodePolyfills(),
|
||||
],
|
||||
base: baseUrl,
|
||||
resolve: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue