【sgUploadTileImage】自定义组件:浏览器端生成瓦片图,并转换为File文件序列上传瓦片图

特性:

  1. 支持自定义瓦片图尺寸
  2. 支持显示预览最小尺寸100x100像素大小,切换为实际切割尺寸
  3. 支持获取切割后的文件Files数组

 sgUploadTileImage源码

<template><div :class="$options.name"><div class="sg-ctrl"><div class="px"><span>瓦片图边长</span><el-input-number style="width: 130px;" v-model.trim="tileSize" :precision="0" :step="100" :min="100":max="500" :controls-position="`left`" /><span>像素</span></div><div class="btns"><el-switch v-model="view100px" inactive-color="#ccc" active-color="#409EFF" inactive-text=""active-text="固定100宽高显示预览" :inactive-value="false" :active-value="true" /><el-button :loading="loading" type="primary" icon="el-icon-upload2"@click="d => $refs.sgUpload.triggerUploadFile()">上传大图</el-button><el-button type="success" icon="el-icon-s-promotion" @click="uploadTiles"v-if="tiles.length">上传瓦片图</el-button></div><div class="tip-text"><p>{{ loadingText }}</p></div></div><div class="sg-tiles" :view100px="view100px"><div :style="{ width: `${(view100px ? 100 : tileSize) * colCount}px` }" v-if="tiles.length"><img v-for="(a, i) in tiles" :key="i" :src="a" :width="view100px ? 100 : tileSize":height="view100px ? 100 : tileSize"></div><el-alert v-else style="width: 555px;height: 50px;margin-top: 10px;" :closable="true" :close-text="``":description="``" :effect="'light'" :show-icon="false" :title="`温馨提示:请上传超大图片文件(大于100M)`" :type="'success'"></el-alert></div><!-- 上传组件 --><sgUpload :disabledWhenShowSels="['.v-modal']" drag ref="sgUpload" :data="{maxSize: 1000,//最大支持上传图片文件1Gaccept: `*`,}" @resultBase64Image="resultBase64Image" @success="uploadSuccess" @error="uploadError" hideUploadTray@showFakeLoading="showFakeLoading" /></div>
</template><script>
import sgUpload from "@/vue/components/admin/sgUpload";
export default {name: 'sgUploadTileImage',components: {sgUpload,},data() {return {loading: false,view100px: true,loadingText: '',colCount: 0,rowCount: 0,src: '',fileFormat: '',tileSize: 500,tiles: [],//瓦片图数组}},watch: {tileSize(d) {this.tiles = [];this.loading = false;this.loadingText = '';},},methods: {uploadTiles(d) {let r = [];let format = this.fileFormat.toLocaleLowerCase().split('/')[1];this.tiles.forEach((base64, i) => {let fileName = `${i}.${format}`;let file = this.$g.image.getFileFromBase64(base64, fileName);r.push(file);});this.$emit(`uploadTiles`, r);},getRowColIndex(itemIndex = 0, colCount = 3) {//必选参数:itemIndex是当前元素的索引值,从0开始计算(如果是从1开始,则需将传入值-1,即itemIndex--)//必选参数:colCount是每一行显示多少个元素return {colIndex: itemIndex % colCount,//计算列索引(从0开始)rowIndex: Math.floor(itemIndex / colCount),//计算行索引(从0开始)        }},// 获取瓦片图getTiles({ img, format = "image/png", cb } = {}) {this.fileFormat = format;let canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');canvas.width = this.tileSize, canvas.height = this.tileSize;let tiles = [];let colCount = Math.ceil(img.width / this.tileSize);//列数量let rowCount = Math.ceil(img.height / this.tileSize);//行数量let len = colCount * rowCount;//瓦片图总数this.loadingText = `已经为您生成${len}个瓦片图(尺寸:${this.tileSize}像素×${this.tileSize}像素)。`;this.colCount = colCount;this.rowCount = rowCount;for (let i = 0; i < len; i++) {let { colIndex, rowIndex } = this.getRowColIndex(i, colCount);let drawImageWidth = colIndex === colCount - 1 ? (img.width % this.tileSize) : this.tileSize;let drawImageHeight = rowIndex === rowCount - 1 ? (img.height % this.tileSize) : this.tileSize;canvas.width = drawImageWidth, canvas.height = drawImageHeight;ctx.drawImage(img,this.tileSize * colIndex, this.tileSize * rowIndex,//绘制图片起始点的横纵坐标drawImageWidth, drawImageHeight,//切割图片的宽高0, 0,//绘制canvas的起始点横纵坐标drawImageWidth, drawImageHeight);//绘制canvas的宽高tiles.push(canvas.toDataURL(format));if (i === len - 1) {let scale = 100 / this.tileSize;this.$el.style.setProperty("--last-img-width", `${drawImageWidth}px`); //js往css传递局部参数this.$el.style.setProperty("--last-img-height", `${drawImageHeight}px`); //js往css传递局部参数this.$el.style.setProperty("--last-img-width-view100px", `${drawImageWidth * scale}px`); //js往css传递局部参数this.$el.style.setProperty("--last-img-height-view100px", `${drawImageHeight * scale}px`); //js往css传递局部参数}}cb && cb(tiles);},/* 将图片(路径)转换为Base64 */resultBase64Image(url, f) {this.tiles = [];this.loadingText = '正在为您分解图片,请稍候!';let img = new Image(); img.crossOrigin = 'Anonymous';img.onload = d => {this.getTiles({img,cb: tiles => {this.tiles = tiles;this.loading = false;}})}img.src = url;},uploadSuccess(d, f) { }, uploadError(d, f) { },showFakeLoading(d) {this.loadingText = '图片上传中,请稍候!';this.loading = true;},}
};
</script>
<style lang="scss" scoped>
.sgUploadTileImage {display: flex;flex-direction: column;.sg-ctrl {display: flex;flex-shrink: 0;flex-wrap: nowrap;align-items: center;.px {margin-right: 10px;span {margin-left: 5px;}}.tip-text {margin-left: 10px;display: flex;align-items: center;}}.sg-tiles {overflow: auto;// max-height: calc(100vh - 100px);flex-grow: 1;div {display: flex;flex-wrap: wrap;img {box-sizing: border-box;border: 0.5px solid white;object-position: top left;object-fit: scale-down;&:last-of-type {border-right: none;border-bottom: none;object-fit: fill;width: var(--last-img-width);height: var(--last-img-height);}}}&[view100px] {div {img {&:last-of-type {width: var(--last-img-width-view100px);height: var(--last-img-height-view100px);}}}}}
}
</style>

用例

<template><div><el-button type="primary" @click="dialogVisible = true">上传超大文件</el-button><el-dialog :custom-class="'sgUploadTileImage-el-dialog'" :append-to-body="true" :close-on-click-modal="true":close-on-press-escape="true" :destroy-on-close="true" :fullscreen="true" :show-close="true" :title="`瓦片图上传`":width="'100%'" :visible.sync="dialogVisible"><div style="width: 100%;height: 100%;"><sgUploadTileImage @uploadTiles="uploadTiles" /></div></el-dialog></div>
</template>
<script>
import sgUploadTileImage from "@/vue/components/admin/sgUploadTileImage";
export default {components: { sgUploadTileImage, },data() {return { dialogVisible: false, }},methods: {uploadTiles(files) {console.log(`瓦片图files:`, files);},},
};
</script> 
<style lang="scss">
.sgUploadTileImage-el-dialog {.el-dialog__body {padding: 0;.sg-tiles {max-height: calc(100vh - 100px);}}
}
</style>

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

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

相关文章

并查集专题

一、并查集的定义 二、基本操作 1、初始化 一开始,每个元素都是独立的集合 #include<iostream>using namespace std;const int maxN=1000; int father[maxN];int</

商场做小程序商城的作用是什么?

商场是众多商家聚集在一起的购物公共场所&#xff0c;大商场也往往入驻着众多行业商家&#xff0c;是每个城市重要的组成部分。 随着互联网电商深入及客户消费行为改变&#xff0c;不少商场如今的客流量非常有限&#xff0c;甚至可以说是员工比客人多&#xff0c;这就导致撤店…

力扣:113. 路径总和 II(Python3)

题目&#xff1a; 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;…

项目集成七牛云存储sdk

以PHP为例 第一步&#xff1a;下载sdk PHP SDK_SDK 下载_对象存储 - 七牛开发者中心 sdk下载成功之后&#xff0c;将sdk放入项目中&#xff0c;目录选择以自己项目实际情况而定。 注意&#xff1a;在examples目录中有各种上传文件的参考示例&#xff0c;这里我们主要参考的是…

高速,低延,任意频丨庚顿新一代实时数据库鼎力支撑电力装备服务数字化

产品同质化日趋严重以及市场需求不断迭代等内外形势下&#xff0c;电力装备制造业自身赢利需求不断增涨&#xff0c;电力等下游产业数字化发展形成倒逼之态&#xff0c;作为国家未来发展的高端装备创新工程主战场&#xff0c;电力装备智能化以及服务型转型升级已经成为装备制造…

晋级名单揭晓,中秋国庆双节喜迎“梧桐杯”省级决赛!

中国移动第三届“梧桐杯”大数据创新大赛自7月启动以来收获全国乃至海外地区高校学子的热烈关注和积极响应&#xff0c;共计630所高校2221支团队报名参赛。参赛团队覆盖全国31省&#xff08;区、市&#xff09;、中国香港、中国澳门以及澳大利亚、法国、新加坡等多个国家和地区…

最新AI智能写作系统ChatGPT源码/支持GPT4.0+GPT联网提问/支持ai绘画Midjourney+Prompt+MJ以图生图+思维导图生成

一、AI创作系统 SparkAi系统是基于很火的GPT提问进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT系统&#xff1f;小编这里写一个详细图文教程吧&#x…

推荐一个好用的电商开源项目yudao源码

1、项目下载cloneruoyi-vue-pro: &#x1f525; 官方推荐 &#x1f525; RuoYi-Vue 全新 Pro 版本&#xff0c;优化重构所有功能。基于 Spring Boot MyBatis Plus Vue & Element 实现的后台管理系统 微信小程序&#xff0c;支持 RBAC 动态权限、数据权限、SaaS 多租户、…

lwip开发指南2

目录 NTP 协议实验NTP 简介NTP 实验硬件设计软件设计下载验证 lwIP 测试网速JPerf 网络测速工具JPerf 网络实验硬件设计软件设计下载验证 HTTP 服务器实验HTTP 协议简介HTTP 服务器实验硬件设计下载验证 网络摄像头&#xff08;ATK-MC5640&#xff09;实验ATK-MC5640 简介SCCB …

idea Springboot 图书管理系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot 图书管理系统是一套完善的信息系统&#xff0c;结合springboot框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#…

分享78个Python源代码总有一个是你想要的

分享78个Python源代码总有一个是你想要的 源码下载链接&#xff1a;https://pan.baidu.com/s/1ZhXDsVuYsZpOUQIUjHU2ww?pwd8888 提取码&#xff1a;8888 下面是文件的名字。 12个python项目源码 Apache Superset数据探查与可视化平台v2.0.1 API Star工具箱v0.7.2 Archery…

python监控ES索引数量变化

文章目录 1, datafram根据相同的key聚合2, 数据合并&#xff1a;获取采集10,20,30分钟es索引数据脚本测试验证 1, datafram根据相同的key聚合 # 创建df1 > json {key:A, value:1 } {key:B, value:2 } data1 {key: [A, B], value: [1, 2]} df1 pd.DataFrame(data1)# 创建d…

Axure RP9 引入eCharts图表

一、 ECharts 地址&#xff1a;https://echarts.apache.org/zh/index.html 概述&#xff1a;一个基于 JavaScript 的开源可视化图表库 提供了很多图标样式案例 二、 Axure引入eCharts图表步骤 步骤一&#xff1a;打开Axure&#xff0c;添加矩形元素&#xff0c;调整矩形所…

CSS详细基础(五)选择器的优先级

本节介绍选择器优先级&#xff0c;优先级决定了元素最终展示的样式~ 浏览器是通过判断CSS优先级&#xff0c;来决定到底哪些属性值是与元素最为相关的&#xff0c;从而作用到该元素上。CSS选择器的合理组成规则决定了优先级&#xff0c;我们也常常用选择器优先级来合理控制元素…

API文档搜索引擎

导航小助手 一、认识搜索引擎 二、项目目标 三、模块划分 四、创建项目 五、关于分词 六、实现索引模块 6.1 实现 Parser类 6.2 实现 Index类 6.2.1 创建 Index类 6.2.2 创建DocInfo类 6.2.3 创建 Weight类 6.2.4 实现 getDocInfo 和 getInverted方法 6.2.5 实现 …

libopenssl 实现私钥加密公钥解密

在需要验证可信来源时&#xff0c;需要用到签名验签。因此&#xff0c;需要使用私钥加密&#xff0c;公钥解密&#xff0c;取得被加密的信息。这就会使用到私钥加密&#xff0c;公钥解密的场景了。 参考&#xff1a; https://github.com/openssl/openssl/issues/20493 https:/…

Bug:elementUI样式不起作用

前端问题合集&#xff1a;VueElementUI 1. Vue引用Element-UI时&#xff0c;组件无效果解决方案 前提&#xff1a; 已经安装好elementUI依赖 //安装依赖 npm install element-ui //main.js中导入依赖并在全局中使用 import ElementUI from element-ui Vue.use(ElementUI)如果此…

C++标准模板库STL——list的使用及其模拟实现

1.list的介绍 list的文档介绍 1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个…

怎么保护苹果手机移动应用程序ipa中文件安全?

目录 前言 1. 对敏感文件进行文件名称混淆 2. 更改文件的MD5值 3. 增加不可见水印处理 3. 对html&#xff0c;js&#xff0c;css等资源进行压缩 5. 删除可执行文件中的调试信息 前言 ios应用程序存储一些图片&#xff0c;资源&#xff0c;配置信息&#xff0c;甚至敏感数…

【AI绘画】Stable Diffusion WebUI

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…