前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >分析snapmaker Luban软件的 导入图片,图片处理的源码

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

作者头像
拿我格子衫来
发布2024-07-15 16:10:42
发布2024-07-15 16:10:42
10500
代码可运行
举报
文章被收录于专栏:TopFETopFE
运行总次数:0
代码可运行

最近要做一个位图转矢量图的功能,设计到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

代码语言:javascript
代码运行次数:0
复制
 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

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

代码语言:javascript
代码运行次数:0
复制
    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);
                });
        });
    },
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档