JS实现选择图片剪裁及保存

news2024/12/25 9:54:29

JS实现选择图片剪裁及保存

以下是一个简单的示例代码,实现了显示一个文件上传框和一个canvas元素。用户可以选择一张图片文件后,该图像将显示在canvas中,并且用户可以通过鼠标拖拽来选取需要剪裁的区域。单击“剪裁”按钮,程序会将结果保存为新的图片文件并在浏览器中下载。

先看效果图:

源码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>JS图片剪裁并保存</title>
</head>
<body>    

    <canvas id="canvas" width="800" height="600" style="border:1px solid #000;"></canvas>

    <div>       
       <input type="file" id="fileInput">
       <button id="cropButton" disabled>剪裁</button> 
       用户可以拖动鼠标来选择需要剪裁的区域       
    </div>

    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let image = null;
        let isDragging = false;
        let startX = 0;
        let startY = 0;
        let endX = 0;
        let endY = 0;

        // 加载图片
        const loadImage = (file) => {
            const reader = new FileReader();
            reader.onload = (e) => {
                image = new Image();
                image.onload = () => {
                    ctx.drawImage(image, 0, 0);
                };
                image.src = e.target.result;
            };
            reader.readAsDataURL(file);
	    disableButtons(); //
        };

        // 监听文件上传事件
        const fileInput = document.getElementById('fileInput');
        fileInput.addEventListener('change', (e) => {
            const file = e.target.files[0];
            loadImage(file);
        });

        // 监听鼠标事件,绘制选择区域
        canvas.addEventListener('mousedown', (e) => {
            if (isDragging) return;
            isDragging = true;
            startX = e.offsetX;
            startY = e.offsetY;
            endX = startX;
            endY = startY;
        });
        canvas.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            endX = e.offsetX;
            endY = e.offsetY;
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.drawImage(image, 0, 0);
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fillRect(startX, startY, endX - startX, endY - startY);
        });
        canvas.addEventListener('mouseup', () => {
            isDragging = false;
            if (endX > startX && endY > startY) {
                enableButtons();
            }
        });

        // 监听确定按钮点击事件,剪裁并保存图片
        const cropButton = document.getElementById('cropButton');
        cropButton.addEventListener('click', () => {
            disableButtons();
            const croppedCanvas = document.createElement('canvas');
            const croppedCtx = croppedCanvas.getContext('2d');
            const width = endX - startX;
            const height = endY - startY;
            croppedCanvas.width = width;
            croppedCanvas.height = height;
            croppedCtx.drawImage(canvas, startX, startY, width, height, 0, 0, width, height);
            const url = croppedCanvas.toDataURL();
            const link = document.createElement('a');
            link.download = 'cropped-image.png';
            link.href = url;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        });

	// 激活按钮
        const enableButtons = () => {
            cropButton.disabled = false;           
        };

        // 禁用按钮
        const disableButtons = () => {
            cropButton.disabled = true;   
        };
       
    </script>
</body>
</html>

OK!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/692624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

8.11 TCP链接管理与UDP协议

目录 TCP的链接管理 TCP包头 连接的建立——”三次握手” 连接的释放——“四次挥手” 保活计时器 UDP协议 计算机网络体系结构 UDP协议 UDP的主要特点 UDP是面向报文的 TCP的链接管理 TCP包头 连接的建立——”三次握手” TCP 建立连接的过程叫做握手。 采用三报文…

java进阶—重要概念反射

反射概念 反射: 它是java中的一个很重要的概念,是框架设计的灵魂 框架呢&#xff1f;就是一个半成品软件&#xff0c;我们在这半成品上进行开发&#xff0c;比如我们经常提到spring springmvc springboot spingcloud 等等 也许有的小伙伴会说&#xff0c;框架别人都写好了&a…

Tdengine 时序数据库-安装与客户端连接

使用 TDengine 时序数据库的版本是 2.4.0.0 使用的安装RPM的安装方便安装 TDengine-server-2.4.0.0-Linux-x64.rpm 1. 安装指令: rpm -ivh TDengine-server-2.4.0.0-Linux-x64.rpm [rootnode3 server]# rpm -ivh TDengine-server-2.4.0.0-Linux-x64.rpm Verifying... …

python的格式化输出

print中的占位符(%-fomatting) print中的%d,%s等&#xff0c;只是一个占位符&#xff0c;等正确内容到了再查进去。 注意&#xff1a;变量值和打印内容之间不能有逗号隔开。 使用fomat方法 format底层可以理解成一个字典&#xff0c;默认key是按顺序从0开始&#xff0c;指定key…

nginxWebUI runCmd RCE漏洞复现

0x01 产品简介 nginxWebUI是一款图形化管理nginx配置的工具&#xff0c;能通过网页快速配置nginx的各种功能&#xff0c;包括HTTP和TCP协议转发、反向代理、负载均衡、静态HTML服务器以及SSL证书的自动申请、续签和配置&#xff0c;配置完成后可以一键生成nginx.conf文件&#…

网络变压器卷盘(封装载带)封膜压力标准

Hqst华强盛导读&#xff1a;网络变压器封装载带封膜压力标准通常是根据具体产品的封装材料和尺寸来确定的。 网络变压器封装载带封膜压力标准通常是根据具体产品的封装材料和尺寸来确定的。一般来说&#xff0c;封装载带的封膜压力应该足够大&#xff0c;以确保封装过程中封膜…

安卓开发基于KeyStore对数据进行加解密

问题背景 在我们App开发过程中&#xff0c;可能会涉及到一些敏感和安全数据需要加密的情况&#xff0c;比如登录token的存储。我们往往会使用一些加密算法将这些敏感数据加密之后再保存起来&#xff0c;需要取出来的时候再进行解密。 此时就会有一个问题&#xff1a;用于加解密…

计算机网络—应用层

文章目录 网络应用基本原理网络应用体系结构~三种结构网络应用进程通信网络应用需求 WEB应用HTTP协议Cookie技术WEB缓存/代理服务器技术 Email应用SMTP协议Email消息格式&#xff08;SMTP传输消息的格式&#xff09;POP3协议IMAP DNS应用DNS协议 网络应用基本原理 网络应用体系…

adb 工具

小白初如嵌入式的坑&#xff0c;对于串口调试工具&#xff0c;之前一直只知道有SecureCRT这一种方式&#xff1b; 但是在最近一次的使用过程中&#xff0c;发现抢占资源的情况出现&#xff0c;两个进程之间相互打架&#xff0c;这个时候需要 查看top&#xff08;嵌入式板子资…

Kernel panic – not syncing: Attempted to kill init! Redhat6.2故障修复

1、Linux环境 Redhat6.2&#xff0c; Linux version 2.6.32-220.el6.i686 (mockbuildx86-003.build.bos.redhat.com) (gccversion 4,4.5 20110214 (Red Hat 4.4.5-6) (GCC) ) #1 SMP Wed Nov 9 08:02:18 EST 2011 2、故障现象 修改TCP相关文件&#xff0c;重启完Linux系统之…

银河麒麟V10搭建达梦8数据库

大家好&#xff0c;我是早九晚十二&#xff0c;目前是做运维相关的工作。写博客是为了积累&#xff0c;希望大家一起进步&#xff01; 我的主页&#xff1a;早九晚十二 目前&#xff0c;国产化服务器越来越多&#xff0c;操作系统的国产化使得大家对中间件都有了需求&#xff0…

alpha值大小对lasso回归结果的影响

LASSO 回归 的特点是在拟合广义线性模型的同时进行变量筛选&#xff08;variable selection&#xff09;和复杂度调整&#xff08;regularization&#xff09;。因此不论目标因变量&#xff08;dependent/response varaible&#xff09;是连续的&#xff08;continuous&#xf…

【FFmpeg实战】视频基础和MP4容器解封装

转载自原文地址&#xff1a;https://juejin.cn/post/6901218687081480206 一、视频的编解码方式 谈到视频&#xff0c;我们经常会听到视频编解码、H.264等诸如此类的内容。那么视频编解码是什么意思呢&#xff1f; 视频编解码&#xff0c;其实就是对视频数据进行压缩和解压缩…

ros版本KF-GINS(带有rviz可视化结果显示及文件生成)

原始的KF-GINS是基于读写文件实现的&#xff0c;在此基础上改进了ros版本&#xff0c;将原始数据文件转换为rosbag格式&#xff0c;并实现了rviz下的可视化结果显示&#xff0c;代码已共享至github https://github.com/slender1031/kf-gins-ros 感谢武汉大学卫星导航定位技术研…

IT培训的背后,是“韭菜”的躺赚梦!

本文只谈"骗局"&#xff0c;不谈其他&#xff0c;绝不引战&#xff0c;如有错误&#xff0c;希望指出我会及时改正。 实际也有大量做得好的、值得肯定的培训机构&#xff0c;这里需要大家仔细鉴别。 导语 为什么要写这篇文章呢&#xff0c;近些年培训这个话题也比较…

Mhz_c1f靶场-简记

靶机 名称&#xff1a;mhz_cxf:clf download url&#xff1a;https://www.vulnhub.com/entry/mhz_cxf-c1f,471/ IP地址探测 sudo netdiscover -i eth1 -r 192.168.56.0/24 sudo netdiscover -i eth1 -r 192.168.56.0/24 Currently scanning: 192.168.56.0/24 | Screen …

ARM Trace32(劳特巴赫) 使用介绍 1 - Veloce 环境中使用 Trace32 介绍

文章目录 背景1.1 Trace 启动1.1.1 Trace32 系统相关设置 1.2 Trace 常用命令1.2.2 加在bin文件1.2.3 寄存器常用命令1.2.4 内存(寄存器)数据修改 1.3 变量相关命令 背景 Veloce是一款基于FPGA的高速仿真器&#xff0c;可用于验证芯片设计和软件开发, 它和 Trace32 都可以用于…

16.RocketMQ之消费重试以及原理

highlight: arduino-light 1.4 消费重试 对于顺序消息,当消费者消费消息失败后,消费者会在本地自动不断进行消息重试,每次间隔时间为 1 秒,重试最大值是 Integer.MAX_VALUE。 对于无序消息(普通、定时、延时、事务消息)当消费者消费消息失败时可以通过设置返回状态达到重试的目…

湿地环境监测物联网解决方案

湿地作为生态系统的关键组成部分&#xff0c;发挥着涵养水源、调节气候、改善环境、维护生物多样性等生态功能。湿地提供了独特的生境&#xff0c;为许多鸟类、鱼类和其他野生动物提供了栖息地和食物来源。此外&#xff0c;湿地还具有保持水量平衡和水质净化的重要功能&#xf…

最优控制:代数黎卡提方程ARE(Algebraic Riccati Equation)

本文介绍代数黎卡提方程的Matlab解法&#xff0c;包括直接求解和迭代求解 问题描述&#xff1a; 一、数值解法 可以看出&#xff0c;ARE方程是关于P的一个非线性方程&#xff0c;当系统矩阵维度较高时&#xff0c;难以求解&#xff0c;但是MATLAB给出了求解ARE的函数care % 系…