diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 27386d7..e85cecc 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,33 +4,11 @@
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -66,87 +44,87 @@
"state": "OPEN"
}
}
- {
+ "prStates": [
{
- "id": {
- "id": "PR_kwDOMJIfts51PkS9",
- "number": 22
+ "id": {
+ "id": "PR_kwDOMJIfts51PkS9",
+ "number": 22
},
- "lastSeen": 1741207144695
+ "lastSeen": 1741207144695
},
{
- "id": {
- "id": "PR_kwDOMJIfts6NiNYl",
- "number": 32
+ "id": {
+ "id": "PR_kwDOMJIfts6NiNYl",
+ "number": 32
},
- "lastSeen": 1741209723869
+ "lastSeen": 1741209723869
},
{
- "id": {
- "id": "PR_kwDOMJIfts6Nheyd",
- "number": 31
+ "id": {
+ "id": "PR_kwDOMJIfts6Nheyd",
+ "number": 31
},
- "lastSeen": 1741213371410
+ "lastSeen": 1741213371410
},
{
- "id": {
- "id": "PR_kwDOMJIfts6NmRBs",
- "number": 33
+ "id": {
+ "id": "PR_kwDOMJIfts6NmRBs",
+ "number": 33
},
- "lastSeen": 1741282429036
+ "lastSeen": 1741282429036
},
{
- "id": {
- "id": "PR_kwDOMJIfts5zyFTs",
- "number": 15
+ "id": {
+ "id": "PR_kwDOMJIfts5zyFTs",
+ "number": 15
},
- "lastSeen": 1741535540953
+ "lastSeen": 1741535540953
},
{
- "id": {
- "id": "PR_kwDOMJIfts6QQB3c",
- "number": 59
+ "id": {
+ "id": "PR_kwDOMJIfts6QQB3c",
+ "number": 59
},
- "lastSeen": 1743018960900
+ "lastSeen": 1743018960900
},
{
- "id": {
- "id": "PR_kwDOMJIfts6QMPEg",
- "number": 58
+ "id": {
+ "id": "PR_kwDOMJIfts6QMPEg",
+ "number": 58
},
- "lastSeen": 1743019452983
+ "lastSeen": 1743019452983
},
{
- "id": {
- "id": "PR_kwDOMJIfts6QZvRI",
- "number": 61
+ "id": {
+ "id": "PR_kwDOMJIfts6QZvRI",
+ "number": 61
},
- "lastSeen": 1743103196866
+ "lastSeen": 1743103196866
},
{
- "id": {
- "id": "PR_kwDOMJIfts6QqPrQ",
- "number": 73
+ "id": {
+ "id": "PR_kwDOMJIfts6QqPrQ",
+ "number": 73
},
- "lastSeen": 1743265865001
+ "lastSeen": 1743265865001
},
{
- "id": {
- "id": "PR_kwDOMJIfts6Qp5nI",
- "number": 72
+ "id": {
+ "id": "PR_kwDOMJIfts6Qp5nI",
+ "number": 72
},
- "lastSeen": 1743338472110
+ "lastSeen": 1743338472110
},
{
- "id": {
- "id": "PR_kwDOMJIfts6QsjlS",
- "number": 76
+ "id": {
+ "id": "PR_kwDOMJIfts6QsjlS",
+ "number": 76
},
- "lastSeen": 1743352150953
+ "lastSeen": 1743352150953
}
]
-}]]>
+}
{
"selectedUrlAndAccountId": {
"url": "https://github.com/iib0011/omni-tools.git",
@@ -199,7 +177,7 @@
"Vitest.replaceText function (regexp mode).should return the original text when passed an invalid regexp.executor": "Run",
"Vitest.replaceText function.executor": "Run",
"Vitest.timeBetweenDates.executor": "Run",
- "git-widget-placeholder": "dark-mode",
+ "git-widget-placeholder": "image-resize",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
"last_opened_file_path": "C:/Users/Ibrahima/IdeaProjects/omni-tools/@types",
@@ -421,22 +399,7 @@
-
-
-
- 1740619610168
-
-
-
- 1740619610169
-
-
-
- 1740620866551
-
-
-
- 1740620866551
+
@@ -814,7 +777,23 @@
1743355166426
-
+
+
+ 1743560690570
+
+
+
+ 1743560690571
+
+
+
+ 1743565606951
+
+
+
+ 1743565606951
+
+
@@ -861,8 +840,6 @@
-
-
@@ -886,7 +863,9 @@
-
+
+
+
diff --git a/src/pages/tools/image/generic/resize/index.tsx b/src/pages/tools/image/generic/resize/index.tsx
index 33ba506..f3df9f5 100644
--- a/src/pages/tools/image/generic/resize/index.tsx
+++ b/src/pages/tools/image/generic/resize/index.tsx
@@ -9,8 +9,10 @@ import ToolContent from '@components/ToolContent';
import { ToolComponentProps } from '@tools/defineTool';
import SimpleRadio from '@components/options/SimpleRadio';
import CheckboxWithDesc from '@components/options/CheckboxWithDesc';
+import { processImage } from './service';
+import { InitialValuesType } from './types';
-const initialValues = {
+const initialValues: InitialValuesType = {
resizeMethod: 'pixels' as 'pixels' | 'percentage',
dimensionType: 'width' as 'width' | 'height',
width: '800',
@@ -19,8 +21,6 @@ const initialValues = {
maintainAspectRatio: true
};
-type InitialValuesType = typeof initialValues;
-
const validationSchema = Yup.object({
width: Yup.number().when('resizeMethod', {
is: 'pixels',
@@ -48,82 +48,9 @@ export default function ResizeImage({ title }: ToolComponentProps) {
const [input, setInput] = useState(null);
const [result, setResult] = useState(null);
- const compute = (optionsValues: InitialValuesType, input: any) => {
+ const compute = async (optionsValues: InitialValuesType, input: any) => {
if (!input) return;
-
- const {
- resizeMethod,
- dimensionType,
- width,
- height,
- percentage,
- maintainAspectRatio
- } = optionsValues;
-
- const processImage = async (file: File) => {
- // Create canvas
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
- if (ctx == null) return;
-
- // Load image
- const img = new Image();
- img.src = URL.createObjectURL(file);
- await img.decode();
-
- // Calculate new dimensions
- let newWidth = img.width;
- let newHeight = img.height;
-
- if (resizeMethod === 'pixels') {
- if (dimensionType === 'width') {
- newWidth = parseInt(width);
- if (maintainAspectRatio) {
- newHeight = Math.round((newWidth / img.width) * img.height);
- } else {
- newHeight = parseInt(height);
- }
- } else {
- // height
- newHeight = parseInt(height);
- if (maintainAspectRatio) {
- newWidth = Math.round((newHeight / img.height) * img.width);
- } else {
- newWidth = parseInt(width);
- }
- }
- } else {
- // percentage
- const scale = parseInt(percentage) / 100;
- newWidth = Math.round(img.width * scale);
- newHeight = Math.round(img.height * scale);
- }
-
- // Set canvas dimensions
- canvas.width = newWidth;
- canvas.height = newHeight;
-
- // Draw resized image
- ctx.drawImage(img, 0, 0, newWidth, newHeight);
-
- // Determine output type based on input file
- let outputType = 'image/png';
- if (file.type) {
- outputType = file.type;
- }
-
- // Convert canvas to blob and create file
- canvas.toBlob((blob) => {
- if (blob) {
- const newFile = new File([blob], file.name, {
- type: outputType
- });
- setResult(newFile);
- }
- }, outputType);
- };
-
- processImage(input);
+ setResult(await processImage(input, optionsValues));
};
const getGroups: GetGroupsType = ({
diff --git a/src/pages/tools/image/generic/resize/service.ts b/src/pages/tools/image/generic/resize/service.ts
new file mode 100644
index 0000000..9b5914d
--- /dev/null
+++ b/src/pages/tools/image/generic/resize/service.ts
@@ -0,0 +1,162 @@
+import { InitialValuesType } from './types';
+
+export const processImage = async (
+ file: File,
+ options: InitialValuesType
+): Promise => {
+ const {
+ width,
+ height,
+ resizeMethod,
+ percentage,
+ dimensionType,
+ maintainAspectRatio
+ } = options;
+ if (file.type === 'image/svg+xml') {
+ try {
+ // Read the SVG file
+ const fileText = await file.text();
+ const parser = new DOMParser();
+ const svgDoc = parser.parseFromString(fileText, 'image/svg+xml');
+ const svgElement = svgDoc.documentElement;
+
+ // Get original dimensions
+ const viewBox = svgElement.getAttribute('viewBox');
+ let originalWidth: string | number | null =
+ svgElement.getAttribute('width');
+ let originalHeight: string | number | null =
+ svgElement.getAttribute('height');
+
+ // Parse viewBox if available and width/height are not explicitly set
+ let viewBoxValues = null;
+ if (viewBox) {
+ viewBoxValues = viewBox.split(' ').map(Number);
+ }
+
+ // Determine original dimensions from viewBox if not explicitly set
+ if (!originalWidth && viewBoxValues && viewBoxValues.length === 4) {
+ originalWidth = String(viewBoxValues[2]);
+ }
+ if (!originalHeight && viewBoxValues && viewBoxValues.length === 4) {
+ originalHeight = String(viewBoxValues[3]);
+ }
+
+ // Default dimensions if still not available
+ originalWidth = originalWidth ? parseFloat(originalWidth) : 300;
+ originalHeight = originalHeight ? parseFloat(originalHeight) : 150;
+
+ // Calculate new dimensions
+ let newWidth = originalWidth;
+ let newHeight = originalHeight;
+
+ if (resizeMethod === 'pixels') {
+ if (dimensionType === 'width') {
+ newWidth = parseInt(width);
+ if (maintainAspectRatio) {
+ newHeight = Math.round((newWidth / originalWidth) * originalHeight);
+ } else {
+ newHeight = parseInt(height);
+ }
+ } else {
+ // height
+ newHeight = parseInt(height);
+ if (maintainAspectRatio) {
+ newWidth = Math.round((newHeight / originalHeight) * originalWidth);
+ } else {
+ newWidth = parseInt(width);
+ }
+ }
+ } else {
+ // percentage
+ const scale = parseInt(percentage) / 100;
+ newWidth = Math.round(originalWidth * scale);
+ newHeight = Math.round(originalHeight * scale);
+ }
+
+ // Update SVG attributes
+ svgElement.setAttribute('width', String(newWidth));
+ svgElement.setAttribute('height', String(newHeight));
+
+ // If viewBox isn't already set, add it to preserve scaling
+ if (!viewBox) {
+ svgElement.setAttribute(
+ 'viewBox',
+ `0 0 ${originalWidth} ${originalHeight}`
+ );
+ }
+
+ // Serialize the modified SVG document
+ const serializer = new XMLSerializer();
+ const svgString = serializer.serializeToString(svgDoc);
+
+ // Create a new file
+ return new File([svgString], file.name, {
+ type: 'image/svg+xml'
+ });
+ } catch (error) {
+ console.error('Error processing SVG:', error);
+ // Fall back to canvas method if SVG processing fails
+ }
+ }
+ // Create canvas
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ if (ctx == null) return null;
+
+ // Load image
+ const img = new Image();
+ img.src = URL.createObjectURL(file);
+ await img.decode();
+
+ // Calculate new dimensions
+ let newWidth = img.width;
+ let newHeight = img.height;
+
+ if (resizeMethod === 'pixels') {
+ if (dimensionType === 'width') {
+ newWidth = parseInt(width);
+ if (maintainAspectRatio) {
+ newHeight = Math.round((newWidth / img.width) * img.height);
+ } else {
+ newHeight = parseInt(height);
+ }
+ } else {
+ // height
+ newHeight = parseInt(height);
+ if (maintainAspectRatio) {
+ newWidth = Math.round((newHeight / img.height) * img.width);
+ } else {
+ newWidth = parseInt(width);
+ }
+ }
+ } else {
+ // percentage
+ const scale = parseInt(percentage) / 100;
+ newWidth = Math.round(img.width * scale);
+ newHeight = Math.round(img.height * scale);
+ }
+
+ // Set canvas dimensions
+ canvas.width = newWidth;
+ canvas.height = newHeight;
+
+ // Draw resized image
+ ctx.drawImage(img, 0, 0, newWidth, newHeight);
+
+ // Determine output type based on input file
+ let outputType = 'image/png';
+ if (file.type) {
+ outputType = file.type;
+ }
+
+ // Convert canvas to blob and create file
+ return new Promise((resolve) => {
+ canvas.toBlob((blob) => {
+ if (blob) {
+ resolve(new File([blob], file.name, { type: outputType }));
+ } else {
+ resolve(null);
+ }
+ }, outputType);
+ });
+};
diff --git a/src/pages/tools/image/generic/resize/types.ts b/src/pages/tools/image/generic/resize/types.ts
new file mode 100644
index 0000000..fe7595e
--- /dev/null
+++ b/src/pages/tools/image/generic/resize/types.ts
@@ -0,0 +1,8 @@
+export type InitialValuesType = {
+ resizeMethod: 'pixels' | 'percentage';
+ dimensionType: 'width' | 'height';
+ width: string;
+ height: string;
+ percentage: string;
+ maintainAspectRatio: boolean;
+};