mjpic 1.0.20 → 1.0.22
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/client/assets/index-DORSlWYO.js +197 -0
- package/dist/client/index.html +1 -1
- package/package.json +2 -2
- package/src/components/layout/CanvasArea.tsx +363 -71
- package/src/components/layout/Header.tsx +112 -13
- package/src/store/useImageStore.ts +77 -0
- package/dist/client/assets/index-BJ_kQgaS.js +0 -197
|
@@ -73,6 +73,82 @@ interface ImageState {
|
|
|
73
73
|
reset: () => void;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
const sanitizeTransparentEdges = (canvas: HTMLCanvasElement) => {
|
|
77
|
+
const ctx = canvas.getContext('2d', { willReadFrequently: true } as any) as CanvasRenderingContext2D | null;
|
|
78
|
+
if (!ctx) return;
|
|
79
|
+
|
|
80
|
+
const { width, height } = canvas;
|
|
81
|
+
if (width <= 1 || height <= 1) return;
|
|
82
|
+
|
|
83
|
+
const imageData = ctx.getImageData(0, 0, width, height);
|
|
84
|
+
const { data } = imageData;
|
|
85
|
+
|
|
86
|
+
const isRowTransparent = (y: number) => {
|
|
87
|
+
for (let x = 0; x < width; x += 1) {
|
|
88
|
+
if (data[(y * width + x) * 4 + 3] !== 0) return false;
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const isColumnTransparent = (x: number) => {
|
|
94
|
+
for (let y = 0; y < height; y += 1) {
|
|
95
|
+
if (data[(y * width + x) * 4 + 3] !== 0) return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const copyRow = (fromY: number, toY: number) => {
|
|
101
|
+
for (let x = 0; x < width; x += 1) {
|
|
102
|
+
const from = (fromY * width + x) * 4;
|
|
103
|
+
const to = (toY * width + x) * 4;
|
|
104
|
+
data[to] = data[from];
|
|
105
|
+
data[to + 1] = data[from + 1];
|
|
106
|
+
data[to + 2] = data[from + 2];
|
|
107
|
+
data[to + 3] = data[from + 3];
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
const copyColumn = (fromX: number, toX: number) => {
|
|
112
|
+
for (let y = 0; y < height; y += 1) {
|
|
113
|
+
const from = (y * width + fromX) * 4;
|
|
114
|
+
const to = (y * width + toX) * 4;
|
|
115
|
+
data[to] = data[from];
|
|
116
|
+
data[to + 1] = data[from + 1];
|
|
117
|
+
data[to + 2] = data[from + 2];
|
|
118
|
+
data[to + 3] = data[from + 3];
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
let top = 0;
|
|
123
|
+
while (top < height && isRowTransparent(top)) top += 1;
|
|
124
|
+
|
|
125
|
+
let bottom = height - 1;
|
|
126
|
+
while (bottom >= 0 && isRowTransparent(bottom)) bottom -= 1;
|
|
127
|
+
|
|
128
|
+
let left = 0;
|
|
129
|
+
while (left < width && isColumnTransparent(left)) left += 1;
|
|
130
|
+
|
|
131
|
+
let right = width - 1;
|
|
132
|
+
while (right >= 0 && isColumnTransparent(right)) right -= 1;
|
|
133
|
+
|
|
134
|
+
if (top >= height || bottom < 0 || left >= width || right < 0) return;
|
|
135
|
+
|
|
136
|
+
for (let y = 0; y < top; y += 1) {
|
|
137
|
+
copyRow(top, y);
|
|
138
|
+
}
|
|
139
|
+
for (let y = bottom + 1; y < height; y += 1) {
|
|
140
|
+
copyRow(bottom, y);
|
|
141
|
+
}
|
|
142
|
+
for (let x = 0; x < left; x += 1) {
|
|
143
|
+
copyColumn(left, x);
|
|
144
|
+
}
|
|
145
|
+
for (let x = right + 1; x < width; x += 1) {
|
|
146
|
+
copyColumn(right, x);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
ctx.putImageData(imageData, 0, 0);
|
|
150
|
+
};
|
|
151
|
+
|
|
76
152
|
const defaultConfig: ImageConfig = {
|
|
77
153
|
rotation: 0,
|
|
78
154
|
scale: 1,
|
|
@@ -225,6 +301,7 @@ export const useImageStore = create<ImageState>((set, get) => ({
|
|
|
225
301
|
}
|
|
226
302
|
|
|
227
303
|
ctx.drawImage(img, -drawWidth / 2, -drawHeight / 2, drawWidth, drawHeight);
|
|
304
|
+
sanitizeTransparentEdges(canvas);
|
|
228
305
|
|
|
229
306
|
const croppedImage = canvas.toDataURL('image/png');
|
|
230
307
|
|