当前位置: 首页 > news >正文

前端实现图片伽玛值调整,并打印调整后的文件

        前段时间去客户现场,客户提出了一个“伽玛值”的需求,啊????伽玛值是什么。。。

        后来看了客户原先系统的“伽玛值”处理效果,结果发现这不就是对图片的锐化值的调整嘛。那么问题来了,这怎么实现呢?属实没接触过啊。但是既然甲方粑粑提出来了,还能怎么办呢,只能硬着头皮写了,又是秃头的一天!!!

1、什么是伽玛值

        在前端开发中,处理伽马值通常涉及到图像的显示和调整,特别是在图像渲染、显示优化和用户交互中。在Web开发中,处理伽马值的操作往往与图像的亮度、对比度以及如何让图像在不同显示设备上表现一致相关。

1.1 伽马值与图像显示

        前端处理伽马值,通常是为了调整图像的显示效果,以便它能够在不同的显示设备上呈现出最佳效果。因为不同的显示器、操作系统和浏览器可能会有不同的色彩和亮度表现,前端开发人员通常需要在图像加载和渲染时对其进行调整。

1.2.伽马校正的应用

在前端开发中,伽马校正通常有以下几种使用场景:

  • 图像加载和显示:在加载图像时,使用JavaScript对其进行伽马值调整,确保图像显示一致,尤其是当图像来源不同,或者浏览器渲染差异较大时。

  • Canvas绘图:在 <canvas> 元素中,伽马校正可能会涉及到像素级别的颜色调整,特别是当绘制图像或进行图像处理时。

  • 色彩空间管理:不同的显示设备和Web环境可能使用不同的色彩空间(例如sRGB或Adobe RGB),前端开发人员可能需要考虑这些色彩空间之间的差异,并对图像或画面进行伽马校正,确保图像显示得尽可能真实。

2、实现代码

        苦苦肝了一天,终于把功能实现了,我这里封装成了一个单独的组件,可以供之后调用,废话不多说,直接上代码。

<template><el-dialog title="伽马值调整":visible.sync="iamgeModel"width="80%"@open="onDialogOpen"@close="onDialogClose"><div><!-- <input type="file"@change="onFileChange"accept="image/*"> --><div v-if="imageSrc"style="margin-top: 20px; text-align: center;"><img :src="imageSrc"alt="预览图"ref="previewImage":style="imageStyle"></div><el-slider v-model="gammaValue":min="0.1":max="3":step="0.01"label="伽玛值"@change="debouncedAdjustImageGamma" /><div style="text-align: center; margin-top: 10px;"><el-button type="primary"@click="printImage">打印</el-button></div></div></el-dialog>
</template>
<script>
import { debounce } from 'lodash'
import { findByEfileIdBase64 } from '@/api/v2/tableData'
export default {data () {return {iamgeModel: false,originalImageSrc: null,imageSrc: null,gammaValue: 1,imageStyle: {maxWidth: '100%',maxHeight: '80vh',objectFit: 'contain'},worker: null, // Web Worker 存储变量debouncedAdjustImageGamma: null, // 防抖函数loadingInstance: null // 加载动画实例}},methods: {init (value) {console.log('value :>> ', value)// 获取图片文件base64findByEfileIdBase64(value).then((result) => {if (result.status != 0) {this.$Message.error('该文件原始文件不是图片类型!')return}console.log('result :>> ', result)let base64String = result.dataconst mimeType = 'image/png' // 根据实际文件类型设置 MIME 类型const file = this.base64ToFile(base64String, 'image.png', mimeType)let efileParams = {base64Value: result,fileObj: file}console.log('efileParams :>> ', efileParams)this.onFileChange(efileParams)})},// base64转换文件对象base64ToFile (base64String, fileName, mimeType) {// 可以直接解码整个 Base64 字符串const byteCharacters = atob(base64String) // 解码 Base64 字符串// 创建一个字节数组const byteArrays = []for (let offset = 0; offset < byteCharacters.length; offset++) {const byte = byteCharacters.charCodeAt(offset)byteArrays.push(byte)}// 创建一个 Blob 对象,指定 MIME 类型const byteArray = new Uint8Array(byteArrays)const blob = new Blob([byteArray], { type: mimeType })// 返回一个 File 对象(可以指定文件名)return new File([blob], fileName, { type: mimeType })},onDialogOpen () {// 在对话框打开时初始化 Web Workerconst workerScript = `self.onmessage = function(e) {const { imageData, gammaValue } = e.data;const data = imageData.data;const gamma = gammaValue;// 遍历每个像素,调整颜色值for (let i = 0; i < data.length; i += 4) {for (let j = 0; j < 3; j++) {let colorValue = data[i + j];colorValue = 255 * Math.pow(colorValue / 255, 1 / gamma);data[i + j] = Math.min(255, Math.max(0, colorValue));}}// 返回处理后的图像数据self.postMessage({ imageData });};`// 使用 Blob 动态创建 Workerconst blob = new Blob([workerScript], { type: 'application/javascript' })this.worker = new Worker(URL.createObjectURL(blob))this.worker.onmessage = (e) => {// 从 Worker 中接收修改后的图像数据const { imageData } = e.dataconst canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.width = imageData.widthcanvas.height = imageData.heightctx.putImageData(imageData, 0, 0)this.imageSrc = canvas.toDataURL() // 获取修改后的图片数据// 完成后关闭加载动画if (this.loadingInstance) {this.loadingInstance.close()}}// 防抖调整图像的函数this.debouncedAdjustImageGamma = debounce(this.adjustImageGamma, 100) // 防抖:每100ms触发一次},onDialogClose () {// 在对话框关闭时销毁 Web Worker 和防抖函数if (this.worker) {this.worker.terminate()this.worker = null}if (this.loadingInstance) {this.loadingInstance.close() // 关闭加载动画}},onFileChange (event) {const file = event.fileObjconsole.log('file :>> ', file)if (file && file.type.startsWith('image')) {const reader = new FileReader()console.log('reader :>> ', reader)reader.onload = (e) => {this.originalImageSrc = e.target.result// 需要一个 base64格式图片this.imageSrc = this.originalImageSrcthis.adjustImageGamma() // 文件上传后立刻处理图像}reader.readAsDataURL(file)}},adjustImageGamma () {// 开始加载时显示 loading 动画this.loadingInstance = this.$loading({lock: true,text: '处理中,请稍候...',background: 'rgba(0, 0, 0, 0.7)'})const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')const img = new Image()img.src = this.originalImageSrcimg.onload = () => {canvas.width = img.widthcanvas.height = img.heightctx.drawImage(img, 0, 0)// 获取图像数据const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)// 发送图像数据到 worker 进行处理if (this.worker) {this.worker.postMessage({ imageData, gammaValue: this.gammaValue })}}},printImage () {const printWindow = window.open('', '_blank')printWindow.document.write('<img src="' + this.imageSrc + '" />')printWindow.print()}}
}
</script>

 

 


http://www.mrgr.cn/news/76445.html

相关文章:

  • redis序列化数据查询
  • python os.path.dirname(path) 详解
  • 【Redis】Redis的一些应用场景及使用策略
  • MySQL【五】
  • 释放 PWA 的力量:2024 年的现代Web应用|React + TypeScript 示例
  • 了解 Solon MVC 的参数注入规则
  • 【提高篇】3.3 GPIO(三,工作模式详解 上)
  • cls(c基础)
  • Docker+Django项目部署-从Linux+Windows实战
  • RHCE的学习(18)
  • 传奇996_19——龙岭总结
  • RHCE的学习(17)
  • Linux设置静态IP
  • Emacs进阶之插入时间信息(一百六十三)
  • Android笔记(三十七):封装一个RecyclerView Item曝光工具——用于埋点上报
  • 微服务即时通讯系统的实现(客户端)----(1)
  • TCP连接秘籍:三次握手建立连接,四次挥手优雅告别
  • 8 软件项目管理
  • 狼蛛F87Pro键盘常用快捷键的使用说明
  • 麒麟kysec安全
  • 数据仓库面试题集离线实时
  • [JAVA]MyBatis环境配置介绍
  • 将已有的MySQL8.0单机架构变成主从复制架构
  • 【AI图像生成网站Golang】项目介绍
  • 2024数证杯电子取证比赛题目(初赛)
  • 1链式有序表的合并