@jsarmyknife/native--file 0.0.1-beta.0 → 1.0.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './web';
1
+ export * from "./web";
package/dist/web.js CHANGED
@@ -22,9 +22,8 @@ function convertFileToBase64(file) {
22
22
  reader.readAsDataURL(file);
23
23
  });
24
24
  }
25
- ;
26
25
  function convertBase64ToFile(base64, filename = "untitled") {
27
- const arr = base64.split(',');
26
+ const arr = base64.split(",");
28
27
  const mime = arr[0].match(/:(.*?);/);
29
28
  if (mime == null || mime[1] == undefined) {
30
29
  throw new Error("Invalid base64 string");
@@ -44,3 +43,55 @@ function getFileLink(fileInput, fileIndex = 0) {
44
43
  let blobURL = URL.createObjectURL(fileInput.files[fileIndex]);
45
44
  return blobURL;
46
45
  }
46
+ async function resizeAndCropImage({ rawImage, downsize, targetAspect }) {
47
+ // Create image element from file
48
+ const img = new Image();
49
+ const imageUrl = URL.createObjectURL(rawImage);
50
+ await new Promise((resolve, reject) => {
51
+ img.onload = () => resolve();
52
+ img.onerror = reject;
53
+ img.src = imageUrl;
54
+ });
55
+ // Parse target aspect ratio (e.g., "2x3" -> 2/3)
56
+ const [aspectWidth, aspectHeight] = targetAspect.split('x').map(Number);
57
+ const targetRatio = aspectWidth / aspectHeight;
58
+ // Target dimensions
59
+ const targetWidth = downsize.width;
60
+ const targetHeight = downsize.height;
61
+ // Calculate source image ratio
62
+ const imgRatio = img.width / img.height;
63
+ let sourceX = 0;
64
+ let sourceY = 0;
65
+ let sourceWidth = img.width;
66
+ let sourceHeight = img.height;
67
+ // Crop to target ratio (centered crop)
68
+ if (imgRatio > targetRatio) {
69
+ // Image is wider - crop width
70
+ sourceWidth = img.height * targetRatio;
71
+ sourceX = (img.width - sourceWidth) / 2;
72
+ }
73
+ else if (imgRatio < targetRatio) {
74
+ // Image is taller - crop height
75
+ sourceHeight = img.width / targetRatio;
76
+ sourceY = (img.height - sourceHeight) / 2;
77
+ }
78
+ // Draw cropped and resized image on canvas
79
+ const canvas = document.createElement('canvas');
80
+ canvas.width = targetWidth;
81
+ canvas.height = targetHeight;
82
+ const ctx = canvas.getContext('2d');
83
+ ctx.drawImage(img, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, targetWidth, targetHeight);
84
+ // Clean up
85
+ URL.revokeObjectURL(imageUrl);
86
+ // Convert canvas to blob then to File
87
+ return new Promise((resolve, reject) => {
88
+ canvas.toBlob((blob) => {
89
+ if (!blob) {
90
+ reject(new Error('Failed to create blob'));
91
+ return;
92
+ }
93
+ const file = new File([blob], rawImage.name, { type: 'image/png' });
94
+ resolve(file);
95
+ }, 'image/png');
96
+ });
97
+ }
package/index.ts CHANGED
@@ -1 +1 @@
1
- export * from './web';
1
+ export * from "./web";
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
- "name": "@jsarmyknife/native--file",
3
- "version": "0.0.1-beta.0",
4
- "public": true,
5
- "description": "All Utilities you need for manipulating files.",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "scripts": {
9
- "build": "tsc"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/JeroTan/JSArmyKnife.git"
14
- },
15
- "author": "Jerowe Tan",
16
- "license": "MIT",
17
- "bugs": {
18
- "url": "https://github.com/JeroTan/JSArmyKnife/issues"
19
- },
20
- "homepage": "https://github.com/JeroTan/JSArmyKnife#readme",
21
- "keywords": []
2
+ "name": "@jsarmyknife/native--file",
3
+ "version": "1.0.2-beta.0",
4
+ "public": true,
5
+ "description": "All Utilities you need for manipulating files.",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsc"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/JeroTan/JSArmyKnife.git"
14
+ },
15
+ "author": "Jerowe Tan",
16
+ "license": "MIT",
17
+ "bugs": {
18
+ "url": "https://github.com/JeroTan/JSArmyKnife/issues"
19
+ },
20
+ "homepage": "https://github.com/JeroTan/JSArmyKnife#readme",
21
+ "keywords": []
22
22
  }
package/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "extends": "../../../tsconfig.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- },
6
- "include": ["index.ts"]
7
- }
2
+ "extends": "../../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist"
5
+ },
6
+ "include": ["index.ts"]
7
+ }
package/web.ts CHANGED
@@ -1,44 +1,118 @@
1
-
2
- export function convertFileToBase64(file:File): Promise<string> {
3
- return new Promise((resolve, reject) => {
4
- const reader = new FileReader();
5
- reader.onload = () => {
6
- if(reader.result == null){
7
- throw new Error("Invalid File");
8
- }
9
- //If array buffer convert it string
10
- if(reader.result instanceof ArrayBuffer){
11
- const arr = new Uint8Array(reader.result);
12
- const str = String.fromCharCode(...arr);
13
- resolve(str);
14
- }
15
- resolve(reader.result as string);
16
- };
17
- reader.onerror = reject;
18
- reader.readAsDataURL(file);
19
- });
20
- };
1
+ export function convertFileToBase64(file: File): Promise<string> {
2
+ return new Promise((resolve, reject) => {
3
+ const reader = new FileReader();
4
+ reader.onload = () => {
5
+ if (reader.result == null) {
6
+ throw new Error("Invalid File");
7
+ }
8
+ //If array buffer convert it string
9
+ if (reader.result instanceof ArrayBuffer) {
10
+ const arr = new Uint8Array(reader.result);
11
+ const str = String.fromCharCode(...arr);
12
+ resolve(str);
13
+ }
14
+ resolve(reader.result as string);
15
+ };
16
+ reader.onerror = reject;
17
+ reader.readAsDataURL(file);
18
+ });
19
+ }
21
20
 
22
21
  export function convertBase64ToFile(base64: string, filename = "untitled"): File {
23
- const arr = base64.split(',');
24
- const mime = arr[0].match(/:(.*?);/);
25
- if(mime == null || mime[1] == undefined){
26
- throw new Error("Invalid base64 string");
27
- }
22
+ const arr = base64.split(",");
23
+ const mime = arr[0].match(/:(.*?);/);
24
+ if (mime == null || mime[1] == undefined) {
25
+ throw new Error("Invalid base64 string");
26
+ }
28
27
 
29
- const bstr = atob(arr[1]);
30
- let n = bstr.length;
31
- const u8arr = new Uint8Array(n);
32
- while(n--){
33
- u8arr[n] = bstr.charCodeAt(n);
34
- }
35
- return new File([u8arr], filename, {type: mime[1]});
28
+ const bstr = atob(arr[1]);
29
+ let n = bstr.length;
30
+ const u8arr = new Uint8Array(n);
31
+ while (n--) {
32
+ u8arr[n] = bstr.charCodeAt(n);
33
+ }
34
+ return new File([u8arr], filename, { type: mime[1] });
35
+ }
36
+
37
+ export function getFileLink(fileInput: HTMLInputElement, fileIndex = 0) {
38
+ if (!fileInput.files) {
39
+ return null;
40
+ }
41
+ let blobURL = URL.createObjectURL(fileInput.files[fileIndex]);
42
+ return blobURL;
36
43
  }
37
44
 
38
- export function getFileLink(fileInput:HTMLInputElement, fileIndex = 0){
39
- if(!fileInput.files){
40
- return null;
45
+
46
+ async function resizeAndCropImage({
47
+ rawImage,
48
+ downsize,
49
+ targetAspect
50
+ }: {
51
+ rawImage: File;
52
+ downsize: { height: number; width: number };
53
+ targetAspect: `${number}x${number}`;
54
+ }): Promise<File> {
55
+ // Create image element from file
56
+ const img = new Image();
57
+ const imageUrl = URL.createObjectURL(rawImage);
58
+
59
+ await new Promise<void>((resolve, reject) => {
60
+ img.onload = () => resolve();
61
+ img.onerror = reject;
62
+ img.src = imageUrl;
63
+ });
64
+
65
+ // Parse target aspect ratio (e.g., "2x3" -> 2/3)
66
+ const [aspectWidth, aspectHeight] = targetAspect.split('x').map(Number);
67
+ const targetRatio = aspectWidth / aspectHeight;
68
+
69
+ // Target dimensions
70
+ const targetWidth = downsize.width;
71
+ const targetHeight = downsize.height;
72
+
73
+ // Calculate source image ratio
74
+ const imgRatio = img.width / img.height;
75
+
76
+ let sourceX = 0;
77
+ let sourceY = 0;
78
+ let sourceWidth = img.width;
79
+ let sourceHeight = img.height;
80
+
81
+ // Crop to target ratio (centered crop)
82
+ if (imgRatio > targetRatio) {
83
+ // Image is wider - crop width
84
+ sourceWidth = img.height * targetRatio;
85
+ sourceX = (img.width - sourceWidth) / 2;
86
+ } else if (imgRatio < targetRatio) {
87
+ // Image is taller - crop height
88
+ sourceHeight = img.width / targetRatio;
89
+ sourceY = (img.height - sourceHeight) / 2;
41
90
  }
42
- let blobURL = URL.createObjectURL(fileInput.files[fileIndex]);
43
- return blobURL;
91
+
92
+ // Draw cropped and resized image on canvas
93
+ const canvas = document.createElement('canvas');
94
+ canvas.width = targetWidth;
95
+ canvas.height = targetHeight;
96
+ const ctx = canvas.getContext('2d')!;
97
+
98
+ ctx.drawImage(
99
+ img,
100
+ sourceX, sourceY, sourceWidth, sourceHeight,
101
+ 0, 0, targetWidth, targetHeight
102
+ );
103
+
104
+ // Clean up
105
+ URL.revokeObjectURL(imageUrl);
106
+
107
+ // Convert canvas to blob then to File
108
+ return new Promise<File>((resolve, reject) => {
109
+ canvas.toBlob((blob) => {
110
+ if (!blob) {
111
+ reject(new Error('Failed to create blob'));
112
+ return;
113
+ }
114
+ const file = new File([blob], rawImage.name, { type: 'image/png' });
115
+ resolve(file);
116
+ }, 'image/png');
117
+ });
44
118
  }