src下的components下新建目录removeBgc,这是我们要自己实现的案例:上传一张图片,将图片的背景消除。
1.安装依赖
hooks库:ahooks
npm i ahooks
组件库:antd
npm i antd
2.removeBgc下新建index.jsx
import React, { useState, useRef } from "react";
import { useAsyncEffect } from "ahooks";
import { Button, Image, Spin, Upload } from "antd";
import { AutoModel, AutoProcessor, env, RawImage } from '@xenova/transformers';
import './index.css';
// Since we will download the model from the Hugging Face Hub, we can skip the local model check
env.allowLocalModels = false;
// Proxy the WASM backend to prevent the UI from freezing
env.backends.onnx.wasm.proxy = true;
const RemoveBgc = () => {
const [isUploaded, setIsUploaded] = useState(false);
const [isAnalyzed, setIsAnalyzed] = useState(false);
const [loading, setLoading] = useState(false);
const [isModelReady, setIsModelReady] = useState(false);
const [isAnalysing, setIsAnalysing] = useState(false);
const [imageSrc, setImageSrc] = useState('');
const [analyzedImageSrc, setAnalyzedImageSrc] = useState('');
const model = useRef();
const processor = useRef();
useAsyncEffect(async () => {
model.current = await AutoModel.from_pretrained('briaai/RMBG-1.4', {
// Do not require config.json to be present in the repository
config: { model_type: 'custom' },
});
processor.current = await AutoProcessor.from_pretrained('briaai/RMBG-1.4', {
// Do not require config.json to be present in the repository
config: {
do_normalize: true,
do_pad: false,
do_rescale: true,
do_resize: true,
image_mean: [0.5, 0.5, 0.5],
feature_extractor_type: "ImageFeatureExtractor",
image_std: [1, 1, 1],
resample: 2,
rescale_factor: 0.00392156862745098,
size: { width: 1024, height: 1024 },
}
});
setIsModelReady(true);
}, [])
const onUpload = ({ file }) => {
if (file.status === 'removed') {
setImageSrc('');
setAnalyzedImageSrc('');
setIsUploaded(false);
setIsAnalyzed(false);
return
}
const reader = new FileReader();
// 文件加载完成后触发的回调
reader.onload = (e) => {
setIsUploaded(true);
setImageSrc(e.target.result);
analysisImage(e.target.result);
};
// 读取文件内容
reader.readAsDataURL(file);
}
const analysisImage = async (url) => {
setIsAnalysing(true);
setLoading(true);
// Read image
const image = await RawImage.fromURL(url);
// Preprocess image
const { pixel_values } = await processor.current(image);
// Predict alpha matte
const { output } = await model.current({ input: pixel_values });
// Resize mask back to original size
const mask = await RawImage.fromTensor(output[0].mul(255).to('uint8')).resize(image.width, image.height);
// Create new canvas
const canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
const ctx = canvas.getContext('2d');
// Draw original image output to canvas
ctx.drawImage(image.toCanvas(), 0, 0);
// Update alpha channel
const pixelData = ctx.getImageData(0, 0, image.width, image.height);
for (let i = 0; i < mask.data.length; ++i) {
pixelData.data[4 * i + 3] = mask.data[i];
}
ctx.putImageData(pixelData, 0, 0);
setAnalyzedImageSrc(canvas.toDataURL());
setIsAnalyzed(true);
setIsAnalysing(false);
setLoading(false);
};
return (
<div className="remove-bgc-container">
<Spin spinning={loading}>
<Upload onChange={onUpload} beforeUpload={() => false} maxCount={1}>
<Button loading={(!isModelReady || isAnalysing)} disabled={(!isModelReady || isAnalysing)} onClick={() => { }}>
{isModelReady ? isAnalysing ? '正在处理...' : '点击上传' : '模型加载中'}
</Button>
</Upload>
<div className="image-container">
{isUploaded && <div>
您上传的图片: <Image src={imageSrc} width={200}></Image>
</div>}
{isAnalyzed && <div>
处理后的图片: <Image src={analyzedImageSrc} width={200}></Image>
</div>}
</div>
</Spin>
</div>
)
}
export default RemoveBgc;
3.removeBgc下新建index.css
.remove-bgc-container {
min-height: 500px;
display: flex;
justify-content: center;
align-items: center;
}
4.修改App.jsx
import React from "react";
// import Transform from "./components/transform";
import RemoveBgc from "./components/removeBgc";
function App() {
return (
<div>
{/* <Transform></Transform> */}
<RemoveBgc></RemoveBgc>
</div>
);
}
export default App;
5.查看效果