【问题标题】:crop image in reactjs using html5 canvas使用HTML5帆布在RESTJS中的裁剪图像
【发布时间】:2020-10-27 11:39:17
【问题描述】:

我正在尝试在不使用任何库的情况下在 reactjs 中裁剪图像。首先,用户将上传图像,用户将使用原始 js 裁剪图像并替换上传的图像。我如何在不使用任何库的情况下做到这一点。我想在 reactjsreference 中使用类似这样的裁剪组件。对我来说 html cansvas 似乎无法使用 html canvas 怎么办?这是沙箱链接:sandbox

这是我为显示图像所做的代码:

import React, { Component } from "react";

class ReactCrop extends Component {
    constructor(props) {
        super(props);

        this.state = {
            file: null,
        };
        this.handleChange = this.handleChange.bind(this)


    }
    handleChange(event) {
        this.setState({
            file: URL.createObjectURL(event.target.files[0])
        })
        console.log("ok",this.state.file)
    }


    saveCroped() {
        const width = 500;
        const height = 300;
        const fileName = e.target.files[0].name;
        const reader = new FileReader();
        reader.readAsDataURL(e.target.files[0]);
        reader.onload = event => {
            const img = new Image();
            img.src = event.target.result;
            img.onload = () => {
                const elem = document.createElement('canvas');
                elem.width = width;
                elem.height = height;
                const ctx = elem.getContext('2d');
                // img.width and img.height will contain the original dimensions
                ctx.drawImage(img, 0, 0, width, height);
                ctx.canvas.toBlob((blob) => {
                    const file = new File([blob], fileName, {
                        type: 'image/jpeg',
                        lastModified: Date.now()
                    });
                }, 'image/jpeg', 1);
            },
                reader.onerror = error => console.log(error);
        };
    }

    componentDidMount() {
        console.log('componentDidMount colling ...');

    }
    render() {

        return (
            <div className="app">
                <div style={{width:'450px', margin:'0 auto'}}>
                    <label htmlFor="file" style={{paddingRight:'80px',marginLeft:'-10px'}}>
                        <input id="files"   type="file" style={{border:'0px',paddingBottom:'12px'}}   key={this.state.inputKey}
                               onChange={this.handleChange}  type="file"/>
                    </label>
                    {this.state.file === null?
                        <p></p>
                        : <img style={{width:'362px',height:'365px',paddingTop:'10px',marginRight:'85px'}} onClick={this.rotate} src={this.state.file}/>

                    }
                </div>
                <button type="button" onClick={() => {this.saveCroped()}}>crop</button>
            </div>
        );
    }
}

export default ReactCrop;

【问题讨论】:

    标签: javascript reactjs html5-canvas crop


    【解决方案1】:

    有趣的问题。这是一个工作示例:(它不会在在线沙箱中下载,但在独立分支上可以正常工作,例如 localhost,请参阅控制台消息)sandbox

    import React, { useRef, useEffect, useState } from "react";
    
    const Crop = function(){
        const canvas = useRef();
        const file = useRef();
        
        const preview = useRef();
        const [imageParams, setImageParams] = useState();
        const [context, setContext] = useState();
    
    
        // Initialize
        useEffect(function(){
    
            file.current.onchange = onNewImage;
            setContext( canvas.current.getContext('2d') );
    
        },[])
    
        // Draw image on imageParams Change
        useEffect(function(){
            if(!imageParams) return;
            
            context.drawImage( preview.current, 0, 0, imageParams.width*(700/imageParams.height), 700 )
            
        }, [imageParams])
    
        // Get with and height, replace preview, set params
        function onNewImage(){
            const newImgUrl = URL.createObjectURL( file.current.files[0] );
            const newImage = document.createElement('img');
    
            newImage.setAttribute('src', newImgUrl);
    
            newImage.onload = function(){
                const {width, height} = newImage;
                const type = file.current.files[0].type
    
                newImage.setAttribute('width', '50px');
    
                preview.current.parentElement.append(newImage);
                preview.current.remove();
    
                preview.current = newImage;
    
                setImageParams({ width, height, type });
            }
        }
    
        // Save image on click
        function handleSave(){
    
            canvas.current.toBlob(function(blob){
                
                const anchor = document.createElement('a');
    
                anchor.innerHTML = 'download';
    
                anchor.download = "my_file."+imageParams.type.replace(/^.{1,}\//,'');
    
                anchor.href = (window.webkitURL || window.URL).createObjectURL(blob);
                anchor.dataset.downloadurl = [imageParams.type, anchor.download, anchor.href].join(':');
                anchor.click();
    
                preview.current.parentElement.append(anchor);
    
            }, imageParams.type);
    
        }
    
        return <>
            <div className="input">
                
                <input 
                    ref={file}
                    type="file"
                    accept="image/png, image/jpeg" />
    
                <div
                    style={{width:"100px", display: 'inline-block'}}>
                    <img
                        
                        ref={preview}
                        />
                </div>
                
    
                <button 
                    onClick={handleSave} >save image</button>
    
            </div>
    
            <div class="canvas">
                <canvas 
                    ref={canvas}
                    width='700px'
                    height='700px' />
            </div>  
    
        </>;
    }
    
    export default Crop;
    

    【讨论】:

    • 是否可以设置纵横比并在我要裁剪的区域中移动鼠标?
    • 当然,正如您可能提到的,我们根据我们之前将画布设置为 700 x 700 的事实绘制图像到上下文。context.drawImage( preview.current, 0, 0, imageParams.width*(700/imageParams.height), 700 ) 意思是 context.drawImage( image, starTop, startLeft, width*renderedAspectRatio, canvasHeight );因此,如果您将画布设置为不同的尺寸比例并相应地将图像渲染到画布,您几乎可以以任何尺寸渲染图像的任何部分。要实现交互式裁剪功能,您将设置一些移动的可调整大小的 div 并在每次调整大小结束事件时将图像重绘到画布。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2011-12-18
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    相关资源
    最近更新 更多