Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在图像边界之外裁剪图像,就像我希望通过添加透明/白色边距从4:3图像生成1:1图像一样?_Javascript_Reactjs_React Redux_Image Manipulation - Fatal编程技术网

Javascript 如何在图像边界之外裁剪图像,就像我希望通过添加透明/白色边距从4:3图像生成1:1图像一样?

Javascript 如何在图像边界之外裁剪图像,就像我希望通过添加透明/白色边距从4:3图像生成1:1图像一样?,javascript,reactjs,react-redux,image-manipulation,Javascript,Reactjs,React Redux,Image Manipulation,目前,我正在使用“react image crop”软件包来裁剪我的图像。但我现在面临的问题是,我需要客户上传一个1:1的公司徽标,但如果图像的形状不是正方形,那么用户将无法上传整个徽标,图像裁剪库将其裁剪为1:1,并删除/去除部分徽标。而我想让它像WhatsApp profile photo upload一样,允许您在图像边界之外裁剪/重塑图像,以使其1:1并添加一些模糊。我只想为新添加的空间添加白色/透明背景。请让我知道是否有一种方法可以使用“react image crop”或任何其他软件

目前,我正在使用“react image crop”软件包来裁剪我的图像。但我现在面临的问题是,我需要客户上传一个1:1的公司徽标,但如果图像的形状不是正方形,那么用户将无法上传整个徽标,图像裁剪库将其裁剪为1:1,并删除/去除部分徽标。而我想让它像WhatsApp profile photo upload一样,允许您在图像边界之外裁剪/重塑图像,以使其1:1并添加一些模糊。我只想为新添加的空间添加白色/透明背景。请让我知道是否有一种方法可以使用“react image crop”或任何其他软件包实现此目的

旁注:实际上我需要一个5:2的图像,而不是1:1。1:1很容易想象/想象,这就是我举这个例子的原因

这就是我的组件的外观:

导出默认函数ImageCrop(道具){
常量[img,setUpImg]=useState()
常量imgRef=useRef(空)
const[crop,setCrop]=useState({单位:'px',宽度:200,纵横比:5/2})
常量[previewUrl,setPreviewUrl]=useState()
useffect(()=>{
onSelectFile(props.file)
}
,[props.file])
const onSelectFile=file=>{
const reader=new FileReader();
reader.addEventListener('load',()=>setUpImg(reader.result));
reader.readAsDataURL(文件);
}
const onLoad=useCallback(img=>{
imgRef.current=img;
}, []);
const makeClientCrop=异步裁剪=>{
if(imgRef.current&&crop.width&&crop.height){
const croped=wait getcropedimg(imgRef.current,crop,props.file.name);
window.URL.revokeObjectURL(previewUrl);
setPreviewUrl(window.URL.createObjectURL(裁剪));
道具更新缓冲(裁剪)
console.log(裁剪)
}
};
函数getcropedimg(图像、裁剪、文件名){
const canvas=document.createElement('canvas');
const scaleX=image.naturalWidth/image.width;
const scaleY=image.naturalHeight/image.height;
canvas.width=crop.width;
canvas.height=crop.height;
const ctx=canvas.getContext('2d');
ctx.drawImage(
形象,,
crop.x*scaleX,
crop.y*scaleY,
crop.width*scaleX,
crop.height*scaleY,
0,
0,
裁剪宽度,
作物高度,
);
//作为Base64字符串
//const base64Image=canvas.toDataURL('image/jpeg');
//一团
返回新承诺((解决、拒绝)=>{
canvas.toBlob(blob=>{
blob.name=文件名;
解决(blob);
}“图像/jpeg”,1);
});
}
返回(
setCrop(c)}
onComplete={makeClientCrop}
样式={{width:'50%}
/>
{previewUrl&&}
)
}

在使用getCroppedImg()方法初始化画布尺寸时,可以选取加载图像的最长一侧,并根据该值创建一个方形画布,然后将图像水平或垂直居中


可能需要在W上添加额外的像素,作为给您更多空间的边距,并按照Andreas在评论中的建议居中调整画布的大小以匹配您的
1:1
/
5:2
纵横比(
canvas.width=…;canvas.height:…;
)在画布的中央而不是左上角(0,0)绘制图像。这个手绘的“答案”真的是答案吗?谢谢你的回答。我对canvas和这个库的引擎盖下的内容一无所知,我只是使用了这个库并从他们的网站上复制粘贴了这个片段。但现在至少我知道我需要寻找什么,以及如何完成它。谢谢你的时间和努力。我会找到答案的!非常感谢你again@Andreas这个手绘答案不是我需要的确切解决方案/代码,但它仍然给了我一个想法/关于该做什么的设想。感谢安德烈亚斯和里卡多·桑切斯的贡献。如果你能得到准确的代码解决方案,那就太好了:)@JasmohanSingh谢谢你的投票,我非常感激,但过早接受答案会妨碍你获得他人的帮助。我建议将问题保留几天,即使有人发布了一些看起来很有希望的东西,也要尝试先编写代码,看看它是否有效,如果您的新尝试不起作用,然后用新代码更新您的问题并对其进行评论,以便我们可以进一步提供帮助。我的回答只是想说明一个可能的解决方案,画东西比写一个长评论要快。好的!我已取消选中“接受答案”选项。谢谢您的指导,我将尝试您的解决方案,并给您反馈,先生。谢谢
    export default function ImageCrop (props){
        const [img, setUpImg] = useState()
        const imgRef = useRef(null)
        const [crop, setCrop] = useState({ unit: 'px', width: 200, aspect: 5 / 2 })
        const [previewUrl, setPreviewUrl] = useState()
        
    
        useEffect(() => {
            
            onSelectFile(props.file)
        }
        ,[props.file])
        const onSelectFile = file => {
          
            const reader = new FileReader();
            reader.addEventListener('load', () => setUpImg(reader.result));
            reader.readAsDataURL(file);
          }
        
      
        const onLoad = useCallback(img => {
          imgRef.current = img;
        }, []);
      
        const makeClientCrop = async crop => {
          if (imgRef.current && crop.width && crop.height) {
            const cropped = await getCroppedImg(imgRef.current, crop, props.file.name);
            window.URL.revokeObjectURL(previewUrl);
              setPreviewUrl(window.URL.createObjectURL(cropped));
              props.updateBuffer(cropped)
             

 console.log(cropped)
        
      }
    };
  
    function getCroppedImg(image, crop, fileName) {
        const canvas = document.createElement('canvas');
        const scaleX = image.naturalWidth / image.width;
        const scaleY = image.naturalHeight / image.height;
        canvas.width = crop.width;
        canvas.height = crop.height;
        const ctx = canvas.getContext('2d');
       
        ctx.drawImage(
          image,
          crop.x * scaleX,
          crop.y * scaleY,
          crop.width * scaleX,
          crop.height * scaleY,
          0,
          0,
          crop.width,
          crop.height,
        );
       
        // As Base64 string
        // const base64Image = canvas.toDataURL('image/jpeg');
       
        // As a blob
        return new Promise((resolve, reject) => {
          canvas.toBlob(blob => {
            blob.name = fileName;
            resolve(blob);
          }, 'image/jpeg', 1);
        });
      }
   
    return (
      <div className="App">
        
        <ReactCrop
          src={img}
          onImageLoaded={onLoad}
          crop={crop}
          onChange={c => setCrop(c)}
          onComplete={makeClientCrop}
          style={{width: '50%'}}
        />
        {previewUrl && <img alt="Crop preview" src={previewUrl} />}
      </div>
    )
    }