分析snapmaker Luban软件的 导入图片,图片处理的源码

最近要做一个位图转矢量图的功能,设计到png,jpg等位图的图像处理算法应用。于是分析一下友商的开源软件,Snapmaker Luban。

主要是图片导入的工具,跟踪选中图片会,代码都是怎么处理的。

我使用的激光模式,

导入图片的工具图片是定义在 SVGLeftBar.jsx
在这里插入图片描述
这里有一个隐藏的文件输入框。当选择文件后,就会触发props.onChangeFile函数。
该函数是从父级组件传下来的,allowedFiles参数定义了能够导入的文件类型,也是从父级组件传下来的。

找一下他的父级组件,搜了一下,父级组件叫做SVGEditor.tsx
在这里插入图片描述

然后我们发现allowedFiles参数与onChangeFile 参数 也是从上游传下来,我们就找。
为什么要费劲找这两个参数那?因为这个两个参数定义这个功能的绝大部份交互和业务逻辑。

SVGEditor.tsx组件被两个组件引用,如下图,我们要找的是LaserVisualizer下的
在这里插入图片描述
在该组件Visualizer.tsx中排查,我们发现参数allowedFiles 最多支持这些格式
.svg, .png, .jpg, .jpeg, .bmp, .dxf, .stl, .amf, .3mf

以下是oncan

 onChangeFile: async (event) => {
   const file = event.target.files[0];
    const extname = path.extname(file.name).toLowerCase();
    if (extname === '.stl' && this.props.materials.isRotate) {
        modal({
            cancelTitle: i18n._('key-Laser/Edit/ContextMenu-Close'),
            title: i18n._('key-Laser/Edit/ContextMenu-Import Error'),
            body: i18n._('Failed to import this object. \nPlease select a supported file format.')
        });
        return;
    }
    let uploadMode;
    if (extname === '.svg') {
        uploadMode = PROCESS_MODE_VECTOR;
    } else if (extname === '.dxf') {
        uploadMode = PROCESS_MODE_VECTOR;
    } else {
        uploadMode = PROCESS_MODE_GREYSCALE;
    }
    this.setState({
        file,
        uploadMode
    });
    // Switch to PAGE_EDITOR page if new image being uploaded
    this.props.switchToPage(PAGE_EDITOR);
    if ((extname === '.stl' || extname === '.amf' || extname === '.3mf') && !this.props.materials.isRotate) {
        this.props.cutModel(file, () => {
            modal({
                cancelTitle: i18n._('key-Laser/Edit/ContextMenu-Close'),
                title: i18n._('key-Laser/Edit/ContextMenu-Import Error'),
                body: i18n._('Failed to import this object. \nPlease select a supported file format.')
            });
        });
    } else if (extname === '.dxf' || extname === '.svg' || extname === '.png' || extname === '.jpg' || extname === '.jpeg' || extname === '.jpeg, .bmp') {
        debugger
        const fileInfo = await this.props.checkIsOversizeImage(file, () => {
            modal({
                cancelTitle: i18n._('key-Laser/Edit/ContextMenu-Close'),
                title: i18n._('key-Laser/Edit/ContextMenu-Import Error'),
                body: i18n._('Failed to import this object. \nPlease select a supported file format.')
            });
        });
        this.fileInfo.current = fileInfo;
    } else {
        this.props.uploadImage(file, uploadMode, () => {
            modal({
                cancelTitle: i18n._('key-Laser/Edit/ContextMenu-Close'),
                title: i18n._('key-Laser/Edit/ContextMenu-Import Error'),
                body: i18n._('Failed to import this object. \nPlease select a supported file format.')
            });
        }, true);
    }
},

当上传png图片后, 触发上游的函数 checkIsOversizeImage

这也是一个比较重要的函数 内容入下

    checkIsOversizeImage: (headType, file, onError) => async (dispatch, getState) => {
        const { materials, progressStatesManager, coordinateSize } = getState()[headType];
        const formData = new FormData();
        formData.append('image', file);
        formData.append('isRotate', materials.isRotate);
        return new Promise((resolve) => {
            api.uploadImage(formData)
                .then(res => {
                    resolve(res.body);
                    // Ensure promise is completed first
                    setTimeout(() => {
                        const { sourceWidth, sourceHeight } = res.body;
                        const isOverSize = isOverSizeModel(coordinateSize, sourceWidth, sourceHeight);
                        dispatch(
                            actions.updateState(headType, {
                                isOverSize: isOverSize
                            })
                        );
                    });
                })
                .catch(err => {
                    resolve();
                    onError && onError(err);
                    dispatch(
                        actions.updateState(headType, {
                            stage: STEP_STAGE.CNC_LASER_UPLOAD_IMAGE_FAILED,
                            progress: 1
                        })
                    );
                    progressStatesManager.finishProgress(false);
                });
        });
    },
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿我格子衫来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值