Commit e3d5185e authored by yaya's avatar yaya

feat:钱币图片添加编辑功能

parent da88a4da
<template>
<div>
<el-dialog
:visible.sync="showCutEditDialog"
:before-close="handleClose"
width="800px"
height="800px"
title="图片操作">
<!-- <div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSelectSuccess">确定</el-button>
</div>-->
<div>
<div class="tool">
<!-- <div>第二步:对去完水印的图片进行抠图</div>-->
<div v-if="!imageBase64 || isCancel" class="select">
<el-button style="width: 95px" @click="handleRemoveLama">去水印</el-button>
<el-button style="width: 150px;margin-top: 20px" @click="handleCut">裁剪</el-button>
</div>
<div v-if="imageBase64 && !isCancel" class="cut">
<VuePictureCut
ref="pictureCut"
:src="imageBase64"
:init-angle="cutInfo.initAngle"
:msk-option="cutInfo.mskOption"
:menu-thickness="cutInfo.menuThickness"
:menu-position="cutInfo.menuPosition"
@on-change="cutChange"
>
<VuePictureCutMask
:width="mastInfo.width"
:height="mastInfo.height"
:is-round="mastInfo.isRound"
:resize="mastInfo.resize"
/>
</VuePictureCut>
</div>
<div v-if="imageBase64 && !isCancel" class="cut-menu">
<div class="shape">
<div>
裁剪形状:
</div>
<div :class="{active: mastInfo.isRound}" class="shape_item" @click="handleChangeShape(1)">
圆形
</div>
<div :class="{active: !mastInfo.isRound}" class="shape_item" @click="handleChangeShape(2)">
正方形
</div>
</div>
<div class="cut-menu">
<vue-picture-cut-menu
:root="pictureCut"
:max-pixel="menuInfo.maxPixel"
:encoder-options="menuInfo.encoderOptions"
:format="menuInfo.format"
theme="gray"
size-auto-name="auto"
size-raw-name="raw"
menu-rotate-name="Rotate"
cancel-name="重置"
confirm-name="裁剪"
@on-change="cutChange"
@on-cancel="cutCancel"
/>
</div>
</div>
</div>
</div>
</el-dialog>
<LamaImageDialog
v-if="showLamaImageDialog"
:show-lama-dialog="showLamaImageDialog"
@closeLamaDialog="showLamaImageDialog = false"
@imageBase64="handleGetImageBase64" />
</div>
</template>
<script>
import { VuePictureCut, VuePictureCutMask, VuePictureCutMenu } from 'vue-picture-cut'
import SelectImageDialog from './selectImageDialog'
import LamaImageDialog from './lamaImageDialog'
export default {
name: 'CutEditImageDialog',
components: { LamaImageDialog, SelectImageDialog, VuePictureCut, VuePictureCutMask, VuePictureCutMenu },
props: {
showCutEditDialog: {
type: Boolean,
default: true
},
/* imageBase64: {
type: String,
default: ''
},*/
editImageUrl: {
type: String,
default: ''
}
},
data() {
return {
pictureCut: null,
// src: this.imageBase64,
cutInfo: {
initAngle: 0,
maxPixel: 500,
encoderOptions: 0.8
},
mastInfo: {
width: 1,
height: 1,
isRound: true,
resize: true
},
menuInfo: {
format: 'image/jpeg/png',
maxPixel: 500,
encoderOptions: 0.8
},
showLamaImageDialog: false,
imageBase64: '',
isCancel: false
}
},
watch: {
imageBase64() {
this.init()
}
},
methods: {
// 初始化图片裁剪工具
// 初始化图片裁剪工具
init() {
if (this.imageBase64) {
setTimeout(() => {
this.pictureCut = this.$refs['pictureCut']
console.log('==7777777777==', this.pictureCut)
}, 1000)
}
},
/**
* 关闭
*/
handleClose() {
this.$emit('cutEditImageDialogClose')
},
// 裁剪图片结果
cutChange(res) {
this.imageBase64 = ''
this.$emit('cutEditSuccess', this.editImageUrl, res.base64)
// console.log('=====blob', this.blob)
console.log('=====base64', this.base64)
},
handlerGetBase64(currentImageUrl, imgUrlBase64) {
this.changeImageUrl = currentImageUrl
if (imgUrlBase64) {
this.imageBase64 = imgUrlBase64
} else {
this.$message.error('获取失败,请重试...')
}
},
// 裁剪工具取消
cutCancel() {
this.isCancel = true
},
// 选择形状
handleChangeShape(type) {
if (type === 1) {
this.mastInfo.isRound = true
} else {
this.mastInfo.isRound = false
}
},
/**
* 去除水印
*/
handleRemoveLama() {
this.isCancel = false
this.copyContent(this.editImageUrl)
this.$message.success('复制链接成功,粘贴链接去水印吧')
this.showLamaImageDialog = true
},
/**
* 复制链接
*/
copyContent(content) {
// 复制结果
let copyResult = true
// 设置想要复制的文本内容
const text = content || ''
// 判断是否支持clipboard方式
if (window.navigator.clipboard) {
// 利用clipboard将文本写入剪贴板(这是一个异步promise)
window.navigator.clipboard.writeText(text).then((res) => {
console.log('复制成功')
// 返回复制操作的最终结果
return copyResult
}).catch((err) => {
copyResult = false
console.log('复制失败', err)
// 返回复制操作的最终结果
return copyResult
})
} else {
// 不支持clipboard方式 则采用document.execCommand()方式
// 创建一个input元素
const inputDom = document.createElement('textarea')
// 设置为只读 防止移动端手机上弹出软键盘
inputDom.setAttribute('readonly', 'readonly')
// 给input元素赋值
inputDom.value = text
// 将创建的input添加到body
document.body.appendChild(inputDom)
// 选中input元素的内容
inputDom.select()
// 执行浏览器复制命令
// 复制命令会将当前选中的内容复制到剪切板中(这里就是创建的input标签中的内容)
// Input要在正常的编辑状态下原生复制方法才会生效
const result = document.execCommand('copy')
// 判断是否复制成功
if (result) {
console.log('复制成功')
} else {
console.log('复制失败')
copyResult = false
}
// 复制操作后再将构造的标签 移除
document.body.removeChild(inputDom)
// 返回复制操作的最终结果
return copyResult
}
},
/**
* 去除水印后的base64结果
* @param imgUrlBase64
*/
handleGetImageBase64(imgUrlBase64) {
this.imageBase64 = imgUrlBase64
this.showLamaImageDialog = false
},
/**
* 点击裁剪,生成base64图片
*/
async handleCut() {
const base64Str = await this.getBase64Image(this.editImageUrl)
this.imageBase64 = base64Str
this.isCancel = false
},
/** url 转换成img */
getBase64Image(img) {
return this.downloadImage(img).then(image => {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
const ext = img.substring(img.lastIndexOf('.') + 1).toLowerCase()
const dataURL = canvas.toDataURL('image/' + ext)
return dataURL
})
},
downloadImage(url) {
return new Promise(resolve => {
const img = new Image()
if (!url) {
resolve(null)
return
}
if (url.indexOf('data:image') !== 0) {
img.crossOrigin = 'Anonymous'
}
img.src = url
img.onload = () => {
resolve(img)
}
img.onerror = (err) => {
console.log(img.src)
console.error(err)
resolve(null)
}
})
}
}
}
</script>
<style lang="scss" scoped>
.tool {
.select {
width: 100%;
height: 230px;
overflow: hidden;
margin: 0 0 20px;
background: white;
border: 1px dashed transparent;
background: linear-gradient(white, white) padding-box,
repeating-linear-gradient(-45deg, #ccc 0, #ccc 0.25em, white 0, white 0.75em);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cut {
width: 100%;
height: 400px;
margin-top: 20px;
}
.cut-menu {
.shape {
display: flex;
flex-direction: row;
height: 80px;
padding-bottom: 20px;
background: #35362e;
justify-content: center;
color: #bbb;
font-size: 14px;
align-items: center;
.shape_item {
border: 1px solid #444;
border-radius: 2px;
width: 60px;
height: 28px;
display: inline-block;
text-align: center;
line-height: 24px;
margin-right: 20px;
&.active {
border: 1px solid #bbb;
}
}
}
}
.tool_content {
margin-left: 20px;
}
}
</style>
<template>
<div>
<el-dialog
:visible.sync="showCutDialog"
:before-close="handleClose"
width="800px"
height="800px"
title="图片裁剪">
<!-- <div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSelectSuccess">确定</el-button>
</div>-->
<div>
<div class="tool">
<!-- <div>第二步:对去完水印的图片进行抠图</div>-->
<div v-if="!imageBase64" class="select">
<el-button style="width: 95px" @click="handleSelectImage(0)">在线选图</el-button>
<el-button style="width: 150px;margin-top: 20px" @click="handleSelectImage(1)">在线选图,去水印</el-button>
<el-button
type="primary"
style="position: relative;overflow: hidden;margin-top: 20px;margin-left: 0px; ">本地上传
<div id="clone_input">
<input
style="position: absolute;top: 0;left: 0;width: 120px;height: 50px;opacity: 0;"
type="file"
accept="image/*"
@change="fileChange">
</div>
</el-button>
</div>
<div v-if="imageBase64" class="cut">
<VuePictureCut
ref="pictureCut"
:src="imageBase64"
:init-angle="cutInfo.initAngle"
:msk-option="cutInfo.mskOption"
:menu-thickness="cutInfo.menuThickness"
:menu-position="cutInfo.menuPosition"
@on-change="cutChange"
>
<VuePictureCutMask
:width="mastInfo.width"
:height="mastInfo.height"
:is-round="mastInfo.isRound"
:resize="mastInfo.resize"
/>
</VuePictureCut>
</div>
<div v-if="imageBase64" class="cut-menu">
<div class="shape">
<div>
裁剪形状:
</div>
<div :class="{active: mastInfo.isRound}" class="shape_item" @click="handleChangeShape(1)">
圆形
</div>
<div :class="{active: !mastInfo.isRound}" class="shape_item" @click="handleChangeShape(2)">
正方形
</div>
</div>
<div class="cut-menu">
<vue-picture-cut-menu
:root="pictureCut"
:max-pixel="menuInfo.maxPixel"
:encoder-options="menuInfo.encoderOptions"
:format="menuInfo.format"
theme="gray"
size-auto-name="auto"
size-raw-name="raw"
menu-rotate-name="Rotate"
cancel-name="重置"
confirm-name="裁剪"
@on-change="cutChange"
@on-cancel="cutCancel"
/>
</div>
</div>
</div>
</div>
</el-dialog>
<SelectImageDialog
v-if="selectImageDialogVisible"
:select-image-dialog-visible="selectImageDialogVisible"
:select-type="selectType"
:image-list="imageList"
@closeDialog="selectImageDialogVisible = false"
@imageBase64Str="handlerGetBase64" />
</div>
</template>
<script>
import { VuePictureCut, VuePictureCutMask, VuePictureCutMenu } from 'vue-picture-cut'
import SelectImageDialog from './selectImageDialog'
export default {
name: 'CutImageDialog',
components: { SelectImageDialog, VuePictureCut, VuePictureCutMask, VuePictureCutMenu },
props: {
showCutDialog: {
type: Boolean,
default: true
},
imageType: {
type: Number,
default: 1
},
/* imageBase64: {
type: String,
default: ''
},*/
imageList: {
type: Array,
default: () => []
},
editImageUrl: {
type: String,
default: ''
}
},
data() {
return {
pictureCut: null,
// src: this.imageBase64,
cutInfo: {
initAngle: 0,
maxPixel: 500,
encoderOptions: 0.8
},
mastInfo: {
width: 1,
height: 1,
isRound: true,
resize: true
},
menuInfo: {
format: 'image/jpeg/png',
maxPixel: 500,
encoderOptions: 0.8
},
selectImageDialogVisible: false,
selectType: 0,
imageBase64: ''
}
},
watch: {
imageBase64() {
this.init()
}
},
methods: {
// 初始化图片裁剪工具
// 初始化图片裁剪工具
init() {
if (this.imageBase64) {
setTimeout(() => {
this.pictureCut = this.$refs['pictureCut']
console.log('==7777777777==', this.pictureCut)
}, 1000)
}
},
/**
* 关闭
*/
handleClose() {
this.$emit('cutImageDialogClose')
},
// 选择图片
handleSelectImage(type) {
if (!this.imageList || this.imageList.length === 0) {
this.$message.error('无线上图片选择')
return
}
this.selectType = type
this.selectImageDialogVisible = true
},
// 选择本地图片结果
fileChange(e) {
if (e.target.files.length) {
this.imageBase64 = URL.createObjectURL(e.target.files[0])
// this.$emit('selectSuccess', URL.createObjectURL(e.target.files[0]))
}
console.log('imageBase64====', this.imageBase64)
},
// 裁剪图片结果
cutChange(res) {
this.imageBase64 = ''
this.$emit('cutSuccess', this.imageType, res)
// console.log('=====blob', this.blob)
console.log('=====base64', this.base64)
},
handlerGetBase64(currentImageUrl, imgUrlBase64) {
this.changeImageUrl = currentImageUrl
if (imgUrlBase64) {
this.imageBase64 = imgUrlBase64
} else {
this.$message.error('获取失败,请重试...')
}
},
// 裁剪工具取消
cutCancel() {
this.$emit('selectSuccess', '')
},
// 选择形状
handleChangeShape(type) {
if (type === 1) {
this.mastInfo.isRound = true
} else {
this.mastInfo.isRound = false
}
}
}
}
</script>
<style lang="scss" scoped>
.tool {
.select {
width: 100%;
height: 230px;
overflow: hidden;
margin: 0 0 20px;
background: white;
border: 1px dashed transparent;
background: linear-gradient(white, white) padding-box,
repeating-linear-gradient(-45deg, #ccc 0, #ccc 0.25em, white 0, white 0.75em);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.cut {
width: 100%;
height: 400px;
margin-top: 20px;
}
.cut-menu {
.shape {
display: flex;
flex-direction: row;
height: 80px;
padding-bottom: 20px;
background: #35362e;
justify-content: center;
color: #bbb;
font-size: 14px;
align-items: center;
.shape_item {
border: 1px solid #444;
border-radius: 2px;
width: 60px;
height: 28px;
display: inline-block;
text-align: center;
line-height: 24px;
margin-right: 20px;
&.active {
border: 1px solid #bbb;
}
}
}
}
.tool_content {
margin-left: 20px;
}
}
</style>
......@@ -8,7 +8,7 @@
title="选择图片">
<div slot="footer" class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSelectSuccess">确定</el-button>
<el-button type="primary" @click="handleSelectCommit">确定</el-button>
</div>
<div class="list">
<div v-for="(item, index) in imageList" :key="item + index" class="select_item" @click="handleCheckImg(index)">
......@@ -65,7 +65,7 @@ export default {
handleCheckImg(index) {
this.currentPosition = index
},
handleSelectSuccess() {
handleSelectCommit() {
if (this.currentPosition === -1) {
this.$message.error('请选择图片')
return
......@@ -76,13 +76,14 @@ export default {
}
if (this.selectType === 1) { // 去水印
this.copyContent(this.imageList[this.currentPosition])
this.$message.info('复制链接成功,粘贴链接去水印吧')
this.$message.success('复制链接成功,粘贴链接去水印吧')
this.showLamaImageDialog = true
this.currentImageUrl = this.imageList[this.currentPosition]
} else {
this.$emit('selectSuccess', this.imageList[this.currentPosition])
this.handleSelectSuccess(this.imageList[this.currentPosition])
/* this.$emit('selectSuccess', this.imageList[this.currentPosition])
this.$emit('closeDialog')
this.currentImageUrl = ''
this.currentImageUrl = ''*/
}
},
handleGetImageBase64(imgUrlBase64) {
......@@ -90,6 +91,50 @@ export default {
this.showLamaImageDialog = false
this.$emit('closeDialog')
},
// 选择线上图片后的图片链接
async handleSelectSuccess(url) {
this.changeImageUrl = url
const base64Str = await this.getBase64Image(url)
this.$emit('imageBase64Str', this.currentImageUrl, base64Str)
this.showLamaImageDialog = false
this.$emit('closeDialog')
console.log('=====&&&&==', base64Str)
},
/** url 转换成img */
getBase64Image(img) {
return this.downloadImage(img).then(image => {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const ctx = canvas.getContext('2d')
ctx.drawImage(image, 0, 0, image.width, image.height)
const ext = img.substring(img.lastIndexOf('.') + 1).toLowerCase()
const dataURL = canvas.toDataURL('image/' + ext)
return dataURL
})
},
downloadImage(url) {
return new Promise(resolve => {
const img = new Image()
if (!url) {
resolve(null)
return
}
if (url.indexOf('data:image') !== 0) {
img.crossOrigin = 'Anonymous'
}
img.src = url
img.onload = () => {
resolve(img)
}
img.onerror = (err) => {
console.log(img.src)
console.error(err)
resolve(null)
}
})
},
copyContent(content) {
// 复制结果
let copyResult = true
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment