chore: image edit api

This commit is contained in:
jialin
2024-12-30 08:37:58 +08:00
parent cb98812444
commit 0b423a6fe0
10 changed files with 125 additions and 29 deletions
+2
View File
@@ -45,6 +45,7 @@ const AutoImage: React.FC<
return;
}
const { ratio } = await getImgRatio(props.src || '');
console.log('ratio', ratio);
if (typeof height === 'number') {
setWidth(height * ratio);
} else {
@@ -66,6 +67,7 @@ const AutoImage: React.FC<
const handleImgLoad = useCallback(() => {
props.onLoad?.();
setIsError(false);
}, [props.onLoad]);
const handleOnError = () => {
+1 -1
View File
@@ -2,7 +2,7 @@ import { createFromIconfontCN } from '@ant-design/icons';
// import './iconfont/iconfont.js';
const IconFont = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4613488_hdf3t88r4j.js'
scriptUrl: '//at.alicdn.com/t/c/font_4613488_bslq45omhet.js'
});
export default IconFont;
+35 -11
View File
@@ -16,7 +16,7 @@ type Stroke = Point[];
type CanvasImageEditorProps = {
imageSrc: string;
disabled?: boolean;
onSave: (imageData: string) => void;
onSave: (imageData: { mask: string; img: string }) => void;
uploadButton: React.ReactNode;
imageStatus: {
isOriginal: boolean;
@@ -131,20 +131,44 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
const maskCanvas = document.createElement('canvas');
maskCanvas.width = overlayCanvas.width;
maskCanvas.height = overlayCanvas.height;
const maskCtx = maskCanvas.getContext('2d');
const maskCtx = maskCanvas.getContext('2d')!;
const overlayCtx = overlayCanvas.getContext('2d')!;
// Create the transparent overlay
maskCtx!.fillStyle = 'black';
maskCtx!.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
maskCtx!.globalCompositeOperation = 'destination-out';
maskCtx!.drawImage(overlayCanvas, 0, 0);
const imageData = overlayCtx.getImageData(
0,
0,
overlayCanvas.width,
overlayCanvas.height
);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const alpha = data[i + 3];
if (alpha > 0) {
data[i] = 255; // Red
data[i + 1] = 255; // Green
data[i + 2] = 255; // Blue
data[i + 3] = 255; // Alpha
}
}
maskCtx.putImageData(imageData, 0, 0);
maskCtx.globalCompositeOperation = 'destination-over';
maskCtx.fillStyle = 'black';
maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
return maskCanvas.toDataURL('image/png');
}, []);
const saveMask = useCallback(() => {
const generateImage = useCallback(() => {
const canvas = canvasRef.current!;
return canvas.toDataURL('image/png');
}, []);
const saveImage = useCallback(() => {
const mask = generateMask();
onSave(mask);
const img = generateImage();
onSave({ mask, img });
}, [onSave, generateMask]);
const downloadMask = useCallback(() => {
@@ -273,7 +297,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
currentStroke.current = [];
saveMask();
saveImage();
};
const clearOverlayCanvas = useCallback(() => {
@@ -560,7 +584,7 @@ const CanvasImageEditor: React.FC<CanvasImageEditorProps> = ({
<div className="tools">
<Tooltip title="Save Mask">
<Button onClick={downloadMask} size="middle" type="text">
<IconFont className="font-size-14" type="icon-save1"></IconFont>
<IconFont className="font-size-14" type="icon-save2"></IconFont>
</Button>
</Tooltip>
<Tooltip title="Download">
+2 -2
View File
@@ -82,7 +82,7 @@ const StatusTag: React.FC<StatusTagProps> = ({
></CopyButton>
{actions?.map((item) => {
return (
<>
<div key={item.key}>
<Divider
style={{
marginBlock: 5,
@@ -99,7 +99,7 @@ const StatusTag: React.FC<StatusTagProps> = ({
<span className="font-size-14">{item.icon}</span>
</Button>
</Tooltip>
</>
</div>
);
})}
</div>