记录一下两年前的一个关于canvas设置手写签名的需求

需求如下:

由于手写区域较大,部分用户手写的区域较小,在盖章的过程中,可能会使得签名笔迹看起来特别小,我们需要将用户真实手写的笔迹进行区域裁剪,得到红框中的部分,使得该图片在盖章展示的时候能看清用户的笔迹

分析设计:

  • 1.由于需要对canvas中已经手写的笔迹进行处理,且手写区域是固定的,一次需要再有一个canvas(adjustCanvas)来处理
  • 2.需要将用户的手写笔迹记录下来,并形成一个矩形区域,在二次绘制的时候,就能确定adjustCanvas的宽高
  • 3.将手写签名的尺寸固定为400*160

要点

1.在touch事件中记录手写区域,包含最小和最大的x、y坐标,因此格式为mEffectivePoint = {
    minX: -1,
    minY: -1,
    maxX: -1,
    maxY: -1,
  }

2.将手写区域的canvas作为原始图片,在重绘前将其赋值到image对象

var image = new Image()
image.src = document.getElementById('myCanvas').toDataURL('image/png')

3.重绘时,需要将canvas的绘图方法需要将原本的图和最终图片的起点和宽高计算出来,该函数定义为:

drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;

关键代码:

  • 设置一个不展示的canvas节点,用来重绘手写签名图片
<div id="work_area" class="canvasContain"><canvas id="idStampAdjustCanvas" class="canvasContentAdjust"></canvas><canvas id="myCanvas" class="canvasContent"></canvas>
</div>
  • 在手写的过程中,记录手写区域
var mEffectivePoint = {minX: -1,minY: -1,maxX: -1,maxY: -1,}////*** 重新计算手写签名的有效区域* @param x* @param y*/function checkEffectivePoint (x, y) {if (x >= 0 && x <= mCanvasWidth) {if (x - mPanWidth < mEffectivePoint.minX || mEffectivePoint.minX === -1) {mEffectivePoint.minX = x - mPanWidthif (mEffectivePoint.minX < 0) {mEffectivePoint.minX = 0}}if (x + mPanWidth > mEffectivePoint.maxX || mEffectivePoint.maxX === -1) {mEffectivePoint.maxX = x + mPanWidthif (mEffectivePoint.maxX > mCanvasWidth) {mEffectivePoint.maxX = mCanvasWidth}}}if (y >= 0 && y <= mCanvasHeight) {if (y - mPanWidth < mEffectivePoint.minY || mEffectivePoint.minY === -1) {mEffectivePoint.minY = y - mPanWidthif (mEffectivePoint.minY < 0) {mEffectivePoint.minY = 0}}if (y + mPanWidth > mEffectivePoint.maxY || mEffectivePoint.maxY === -1) {mEffectivePoint.maxY = y + mPanWidthif (mEffectivePoint.maxY > mCanvasHeight) {mEffectivePoint.maxY = mCanvasHeight}}}}function touchStart (event) {event.preventDefault()HAS_IMAGE = truefor (var i = 0; i < event.touches.length; i++) {checkEffectivePoint(event.touches[i].pageX - mCanvasOffsetLeft, event.touches[i].pageY - mCanvasOffsetTop)paths.push({id: event.touches[i].identifier,points: [{x: event.touches[i].pageX - mCanvasOffsetLeft,y: event.touches[i].pageY - mCanvasOffsetTop,timestamp: new Date().getTime(),drawn: false,}],complete: false,})}}function touchEnd (event) {event.preventDefault()for (var i = 0; i < event.changedTouches.length; i++) {for (var j = 0; j < paths.length; j++) {if (paths[j].id == event.changedTouches[i].identifier) {paths[j].id = nullpaths[j].complete = true}}}}function touchMove (event) {event.preventDefault()for (var i = 0; i < event.touches.length; i++) {for (var j = 0; j < paths.length; j++) {if (paths[j].id == event.touches[i].identifier) {checkEffectivePoint(event.touches[i].pageX - mCanvasOffsetLeft, event.touches[i].pageY - mCanvasOffsetTop)paths[j].points.push({x: event.touches[i].pageX - mCanvasOffsetLeft,y: event.touches[i].pageY - mCanvasOffsetTop,drawn: false,timestamp: new Date().getTime(),})}}}}
  • 补充需求—将手写签名的区域固定为400*160
// 我们将图章设置为400*160的尺寸保存到服务端var stampMaxX = 400var stampMaxY = 160/**** 根据原始图片的宽高,在限定尺寸的canvas中配置好绘图起始点坐标和宽高,让图片能够不变形地完全绘制在限定尺寸的canvas中* @param width 真实手写的宽* @param height  真实手写区域的高度* canvas的尺寸(maxX=400,maxY=160)* 1-原始图片width<maxX*   1-1 height<maxY*   1-2 height>=maxY* 2-原始图片width>=maxX*   2-1 width/maxX > height/maxY (宽度的比例大于高度的比例)*   2-2 width/maxX <= height/maxY** @return {{width: number, startY: number, startX: number, height: number}}*/function getDrawArea (width, height) {var drawStartPoint = {startX: 0,  //重绘起点的x坐标startY: 0,  //重绘起点的y坐标width: stampMaxX, //重绘图片的宽height: stampMaxY,  //重绘图片的高}if (width < stampMaxX) {if (height < stampMaxY) {drawStartPoint = {startX: (stampMaxX - width) / 2,startY: (stampMaxY - height) / 2,width: width,height: height,}} else {var scale = stampMaxY / heightdrawStartPoint = {startX: (stampMaxX - width * scale) / 2,startY: 0,width: width * scale,height: stampMaxY,}}} else {var scaleWidth = stampMaxX / widthvar scaleHeight = stampMaxY / heightvar scale = scaleWidthif (width / height > stampMaxX / stampMaxY) {// 说明图片相对比例,缩放后,width更小,所以以height为基准边scale = scaleWidthdrawStartPoint = {startX: 0,startY: (stampMaxY - height * scale) / 2,width: stampMaxX,height: height * (stampMaxX / width),}} else {scale = scaleHeightdrawStartPoint = {startX: (stampMaxX - width * scale) / 2,startY: 0,width: width * (stampMaxY / height),height: stampMaxY,}}}return drawStartPoint}// ....其他逻辑代码/*** 根据手写区域裁剪图片*/function getImageByEffectiveArea (imageSource, callback) {var effectivePoint = {minX: mEffectivePoint.minX,maxX: mEffectivePoint.maxX === mEffectivePoint.minX ? mEffectivePoint.minX + 10 : mEffectivePoint.maxX,minY: mEffectivePoint.minY,maxY: mEffectivePoint.maxY === mEffectivePoint.minX ? mEffectivePoint.maxY + 10 : mEffectivePoint.maxY,}canvas2 = document.getElementById('idStampAdjustCanvas')context2 = canvas2.getContext('2d')//先清除context2.clearRect(0, 0, canvas2.width, canvas2.height)var width = effectivePoint.maxX - effectivePoint.minXvar height = effectivePoint.maxY - effectivePoint.minYcanvas2.width = stampMaxXcanvas2.height = stampMaxYloadImage(imageSource.src, function () {context2 = canvas2.getContext('2d')var drawStartPoint = getDrawArea(width, height)context2.drawImage(imageSource,effectivePoint.minX, effectivePoint.minY, width, height,drawStartPoint.startX, drawStartPoint.startY,drawStartPoint.width, drawStartPoint.height)callback(canvas2.toDataURL('image/png'))})}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>签名笔迹设置</title><meta name="viewport" content="initial-scale=1.0, user-scalable=no"/><meta name="apple-mobile-web-app-capable" content="yes"/><style type="text/css">* {padding: 0;margin: 0;-webkit-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none;}html {height: 100%;width: 100%;}body {height: 100%;width: 100%;box-sizing: border-box;-moz-box-sizing: border-box; /* Firefox */-webkit-box-sizing: border-box; /* Safari */display: flex;display: -webkit-flex;display: inline-flex;display: -moz-flex;display: -ms-flexbox;flex-direction: row;-webkit-flex-direction: row;}.canvasContain {display: flex;flex: 1;position: relative;}.canvasContent {display: block;width: 100%;z-index: 99;/*background-color: #FFF;*/background: #FFF url(./image/bg_canvas.png) no-repeat fixed center;}.canvasContentAdjust {position: absolute;display: none;background-color: #F2F2F2;z-index: 1;width: 400px;height: 160px;}.rightContain {display: flex;display: -webkit-flex;justify-content: flex-end;-webkit-justify-content: flex-end;flex-direction: column;-webkit-flex-direction: column;align-items: center;width: 60px;background-color: #F2F2F2;padding-bottom: 20px;}.penContain {width: 60px;height: 45px;text-align: center;vertical-align: middle;display: flex;display: -webkit-flex;justify-content: center;-webkit-justify-content: center;flex-direction: column;-webkit-flex-direction: column;box-sizing: border-box;-moz-box-sizing: border-box; /* Firefox */-webkit-box-sizing: border-box; /* Safari */}.pen {margin: 0 auto;display: flex;border: solid 2px transparent;background-color: #000;border-radius: 50%;}.i1 {width: 10px;height: 10px;}.i2 {width: 14px;height: 14px;}.i3 {width: 18px;height: 18px;}.on {border: solid 2px #999;}.delete {color: #333;background: url(./image/del.png) no-repeat center center;background-size: 80% 100%;outline: none;}.save {color: #333;background: url(./image/signed.png) no-repeat center center;background-size: 80% 100%;outline: none;}.click-image {margin-top: 15px;width: 60px;height: 40px;/*transform: rotate(-90deg);*/border: 0 none;position: relative;z-index: auto;}</style>
</head><body><!-- 正文 -->
<div id="work_area" class="canvasContain"><canvas id="idStampAdjustCanvas" class="canvasContentAdjust"></canvas><canvas id="myCanvas" class="canvasContent"></canvas><!--    <img id='signImg' src='draw/image/canvas_bg1.png'/>-->
</div><div class="rightContain"><div class="penContain" onclick="setPenWidth(3)"><div class="pen i1" id="idPenSmall"></div></div><div class="penContain" onclick="setPenWidth(5)"><div class="pen i2 on" id="idPenNormal"></div></div><div class="penContain" onclick="setPenWidth(8)"><div class="pen i3" id="idPenMax"></div></div><div class="H5_footer pull-left btncon"><button class="click-image delete" onclick="clean()"></button><button class="click-image save" onclick="save()"></button></div>
</div><script type="text/javascript">var CANVAS_WIDTH = 0var CANVAS_HEIGHT = 0// 我们将图章设置为400*160的尺寸保存到服务端var stampMaxX = 400var stampMaxY = 160var PAN_WIDTH_SMALL = 3var PAN_WIDTH_NORMAL = 5var PAN_WIDTH_BIG = 8var MAX_VELOCITY = 10var context = nullvar HAS_IMAGE = falsevar scale = 1var mCanvasWidth = 0var mCanvasHeight = 0var mCanvasOffsetLeft = 0var mCanvasOffsetTop = 0var base_url = nullvar token = nullvar mStartPoint = {x: 0,y: 0,}var mEndPoint = {x: 0,y: 0,}var mPanWidth = PAN_WIDTH_NORMALvar canvas2var context2var mEffectivePoint = {minX: -1,minY: -1,maxX: -1,maxY: -1,}var paths = []function clean () {context.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT)HAS_IMAGE = falseinitEffectivePoint()return false}function setPenWidth (width) {mPanWidth = widthremoveSelectPenStyle()if (width > PAN_WIDTH_NORMAL) {document.getElementById('idPenMax').className = 'pen i3 on'} else if (width < PAN_WIDTH_NORMAL) {document.getElementById('idPenSmall').className = 'pen i1 on'} else {document.getElementById('idPenNormal').className = 'pen i2 on'}console.log(document.getElementById('idPenSmall').className)console.log(document.getElementById('idPenNormal').className)console.log(document.getElementById('idPenMax').className)}function removeSelectPenStyle () {document.getElementById('idPenSmall').className = 'pen i1'document.getElementById('idPenNormal').className = 'pen i2'document.getElementById('idPenMax').className = 'pen i3'}function init () {CANVAS_WIDTH = document.body.clientWidth - 60CANVAS_HEIGHT = document.body.clientHeightvar canvas = document.getElementById('myCanvas')mCanvasWidth = CANVAS_WIDTHmCanvasHeight = CANVAS_HEIGHTcanvas.height = CANVAS_HEIGHTcanvas.width = CANVAS_WIDTHcontext = canvas.getContext('2d')var image = new Image()if (image.src != 'data:image/png;base64,null') {preImage(image.src, function () {context.drawImage(this, 0, 0, this.width * scale, this.height * scale)HAS_IMAGE = true})}context.lineWidth = mPanWidthcontext.fillStyle = '#000000'context.strokeStyle = '#000000'context.lineCap = 'round'context.lineJoin = 'miter'canvas.addEventListener('touchmove', touchMove, false)canvas.addEventListener('touchstart', touchStart, false)canvas.addEventListener('touchend', touchEnd, false)function preImage (url, callback) {var img = new Image() //创建一个Image对象,实现图片的预下载img.src = urlif ((url.indexOf('null') <= 0) && (url.length > 50)) //判断图片非空{if (img.complete) {//如果图片已经存在于浏览器缓存,直接调用回调函数callback.call(img)return // 直接返回,不用再处理onload事件}img.onload = function () { //图片下载完毕时异步调用callback函数。callback.call(img)//将回调函数的this替换为Image对象}}}setInterval(draw, 20)}function drawLine (startPoint, endPoint) {context.lineWidth = mPanWidthcontext.beginPath()context.moveTo(startPoint.x, startPoint.y)context.lineTo(endPoint.x, endPoint.y)context.stroke()context.closePath()mStartPoint = endPoint}function touchStart (event) {event.preventDefault()HAS_IMAGE = truefor (var i = 0; i < event.touches.length; i++) {checkEffectivePoint(event.touches[i].pageX - mCanvasOffsetLeft, event.touches[i].pageY - mCanvasOffsetTop)paths.push({id: event.touches[i].identifier,points: [{x: event.touches[i].pageX - mCanvasOffsetLeft,y: event.touches[i].pageY - mCanvasOffsetTop,timestamp: new Date().getTime(),drawn: false,}],complete: false,})}}function touchEnd (event) {event.preventDefault()for (var i = 0; i < event.changedTouches.length; i++) {for (var j = 0; j < paths.length; j++) {if (paths[j].id == event.changedTouches[i].identifier) {paths[j].id = nullpaths[j].complete = true}}}}function touchMove (event) {event.preventDefault()for (var i = 0; i < event.touches.length; i++) {for (var j = 0; j < paths.length; j++) {if (paths[j].id == event.touches[i].identifier) {checkEffectivePoint(event.touches[i].pageX - mCanvasOffsetLeft, event.touches[i].pageY - mCanvasOffsetTop)paths[j].points.push({x: event.touches[i].pageX - mCanvasOffsetLeft,y: event.touches[i].pageY - mCanvasOffsetTop,drawn: false,timestamp: new Date().getTime(),})}}}}function draw () {var DRAW_TIME_THRESHOLD = 10var start = new Date()context.lineWidth = mPanWidthfor (var i = 0; i < paths.length&& new Date() - start < DRAW_TIME_THRESHOLD; i++) {var firstPoint = truevar points = paths[i].pointsif (points.length > 1 && points[points.length - 1].drawn == false) {context.beginPath()for (var j = 1; j < points.length; j++) {if (firstPoint && points[j].drawn == false) {firstPoint = falsecontext.moveTo(points[j - 1].x, points[j - 1].y)points[j - 1].drawn = truecontext.lineTo(points[j].x, points[j].y)} else if (points[j].drawn == false) {context.lineTo(points[j].x, points[j].y)}points[j].drawn = true}context.stroke()context.closePath()} else if (paths[i].complete && points[0].drawn == false) {context.arc(points[0].x, points[0].y, context.lineWidth / 2, 0,Math.PI * 2, false)context.closePath()context.fill()points[0].drawn = true}}}/*** 重新计算手写签名的有效区域* @param x* @param y*/function checkEffectivePoint (x, y) {if (x >= 0 && x <= mCanvasWidth) {if (x - mPanWidth < mEffectivePoint.minX || mEffectivePoint.minX === -1) {mEffectivePoint.minX = x - mPanWidthif (mEffectivePoint.minX < 0) {mEffectivePoint.minX = 0}}if (x + mPanWidth > mEffectivePoint.maxX || mEffectivePoint.maxX === -1) {mEffectivePoint.maxX = x + mPanWidthif (mEffectivePoint.maxX > mCanvasWidth) {mEffectivePoint.maxX = mCanvasWidth}}}if (y >= 0 && y <= mCanvasHeight) {if (y - mPanWidth < mEffectivePoint.minY || mEffectivePoint.minY === -1) {mEffectivePoint.minY = y - mPanWidthif (mEffectivePoint.minY < 0) {mEffectivePoint.minY = 0}}if (y + mPanWidth > mEffectivePoint.maxY || mEffectivePoint.maxY === -1) {mEffectivePoint.maxY = y + mPanWidthif (mEffectivePoint.maxY > mCanvasHeight) {mEffectivePoint.maxY = mCanvasHeight}}}}/*** 保存图片*/function save () {var image = new Image()// var imgSrc = canvas.toDataURL("image/png");image.src = document.getElementById('myCanvas').toDataURL('image/png')if (HAS_IMAGE) {getImageByEffectiveArea(image, function (img) {if (window.ReactNativeWebView) {// react-native的webview修改为react-native-webview组件,需要使用一下方式进行通信window.ReactNativeWebView.postMessage(img)initEffectivePoint()} else if (window.postMessage) {window.postMessage(img)initEffectivePoint()} else {alert('浏览器暂不支持此操作')}})} else {/*** 点击保存签章判断,画布是否有内容* 如果画布为空,参数为null* */window.ReactNativeWebView.postMessage('null')}}/*** 根据手写区域裁剪图片*/function getImageByEffectiveArea (imageSource, callback) {var effectivePoint = {minX: mEffectivePoint.minX,maxX: mEffectivePoint.maxX === mEffectivePoint.minX ? mEffectivePoint.minX + 10 : mEffectivePoint.maxX,minY: mEffectivePoint.minY,maxY: mEffectivePoint.maxY === mEffectivePoint.minX ? mEffectivePoint.maxY + 10 : mEffectivePoint.maxY,}canvas2 = document.getElementById('idStampAdjustCanvas')context2 = canvas2.getContext('2d')//先清除context2.clearRect(0, 0, canvas2.width, canvas2.height)var width = effectivePoint.maxX - effectivePoint.minXvar height = effectivePoint.maxY - effectivePoint.minYcanvas2.width = stampMaxXcanvas2.height = stampMaxYloadImage(imageSource.src, function () {context2 = canvas2.getContext('2d')var drawStartPoint = getDrawArea(width, height)console.log(width, height, drawStartPoint)context2.drawImage(imageSource,effectivePoint.minX, effectivePoint.minY, width, height,drawStartPoint.startX, drawStartPoint.startY,drawStartPoint.width, drawStartPoint.height)callback(canvas2.toDataURL('image/png'))})}/**** 根据原始图片的宽高,在限定尺寸的canvas中配置好绘图起始点坐标和宽高,让图片能够不变形地完全绘制在限定尺寸的canvas中* @param width 真实手写的宽* @param height  真实手写区域的高度* canvas的尺寸(maxX=400,maxY=160)* 1-原始图片width<maxX*   1-1 height<maxY*   1-2 height>=maxY* 2-原始图片width>=maxX*   2-1 width/maxX > height/maxY (宽度的比例大于高度的比例)*   2-2 width/maxX <= height/maxY** @return {{width: number, startY: number, startX: number, height: number}}*/function getDrawArea (width, height) {var drawStartPoint = {startX: 0,  //重绘起点的x坐标startY: 0,  //重绘起点的y坐标width: stampMaxX, //重绘图片的宽height: stampMaxY,  //重绘图片的高}if (width < stampMaxX) {if (height < stampMaxY) {drawStartPoint = {startX: (stampMaxX - width) / 2,startY: (stampMaxY - height) / 2,width: width,height: height,}console.log(111111)} else {var scale = stampMaxY / heightdrawStartPoint = {startX: (stampMaxX - width * scale) / 2,startY: 0,width: width * scale,height: stampMaxY,}console.log(222222, scale)}} else {var scaleWidth = stampMaxX / widthvar scaleHeight = stampMaxY / heightvar scale = scaleWidthif (width / height > stampMaxX / stampMaxY) {// 说明图片相对比例,缩放后,width更小,所以以height为基准边scale = scaleWidthdrawStartPoint = {startX: 0,startY: (stampMaxY - height * scale) / 2,width: stampMaxX,height: height * (stampMaxX / width),}} else {scale = scaleHeightdrawStartPoint = {startX: (stampMaxX - width * scale) / 2,startY: 0,width: width * (stampMaxY / height),height: stampMaxY,}}}return drawStartPoint}function loadImage (url, callback) {var img = new Image() // 创建一个Image对象,实现图片的预下载img.src = urlif (img.complete) {// 如果图片已经存在于浏览器缓存,直接调用回调函数callback.call(img)}img.onload = function () { // 图片下载完毕时异步调用callback函数。callback.call(img)// 将回调函数的this替换为Image对象}}function initEffectivePoint () {mEffectivePoint = {minX: -1,minY: -1,maxX: -1,maxY: -1,}}setTimeout(function () {// 延时进行init,需要等页面渲染完成后再初始化canvasinit()}, 600)
</script>
</body></html>

canvas书写图片并修改尺寸相关推荐

  1. 图片批量修改尺寸如何实现?

    图片批量修改尺寸如何实现?不管是谁,在工作中或者在学习时或多或少都需要使用到图片.小刘是一个刚参加工作的白领,从事的是电商行业,所以经常需要修改图片尺寸大小,这个操作对于小刘来并不是一件难事,只需要一 ...

  2. matlab读取一个文件的图片大小,Matlab读取文件夹中子文件夹中的图片并修改尺寸...

    今天被师兄问到如何利用matlab批处理图片,觉得很简单嘛 就让他去百度 结果只百度到处理文件夹中图片的程序 好吧 这里放上如何处理文件夹中子文件夹的图片 现状:在一个名为casia的文件夹中,里面有 ...

  3. ios 裁剪框大小_ios 图片裁剪修改尺寸的方法总结

    目前使用过的图片裁剪方法 1.等比例压缩 裁剪出的图片是以asize最小值为边框的正方形图片 //修改图片尺寸同比缩放 + (UIImage*)thumbnailWithImageWithoutSca ...

  4. 怎样修改图片尺寸比例?图片大小修改在线修改的方法

    生活中如果遇到图片尺寸比例不符合使用要求时,许多小伙伴不知道怎么快读将图片大小修改(https://www.yasuotu.com/size),本文将介绍一个在线改图片大小工具,打开浏览器即可完成图片 ...

  5. 怎么修改图片长宽尺寸?如何用电脑修改照片尺寸?

    自媒体编辑工作的小伙伴经常需要修改图片尺寸(https://www.yasuotu.com/size)来应对不同平台的图片尺寸大小要求,那么如何改图片大小呢?接下来本文将带给大家一些关于图片改大小的相 ...

  6. canvas 实现图片局部模糊_JavaScript中的图片处理与合成(四)

    引言: 本系列现在构思成以下4个部分: 基础类型图片处理技术之缩放.裁剪与旋转(传送门): 基础类型图片处理技术之图片合成(传送门): 基础类型图片处理技术之文字合成(传送门): 算法类型图片处理技术 ...

  7. canvas - 绘制图片,图片变模糊问题解决)

    问题:canvas绘制图片,图片变模糊 设定一个一定尺寸的canvas,我这里设置的画布大小是400px*400px.当一张图片完全画到画布上的时候,大概率都会出现图片模糊的情况. 我拿下面一张图片画 ...

  8. canvas绘制图片,图片变模糊

    canvas绘制图片,图片变模糊 问题: 设定一个一定尺寸的canvas,我这里设置的画布大小是400px*400px.当一张图片完全画到画布上的时候,大概率都会出现图片模糊的情况. 我拿下面一张图片 ...

  9. 神奇的canvas——巧用 canvas 为图片添加水印

    代码地址如下: http://www.demodashi.com/demo/11637.html 很久之前写过一篇关于 canvas 的文章,是通过 canvas 来实现一个绚丽的动画效果,不管看过没 ...

  10. 图片1920x1080分辨率怎么调 ?图片如何修改分辨率?

    图片是我们日常生活中经常需要使用到的东西,但是在使用图片时我们会遇到需要调图片分辨率的情况,有很多小伙伴对于图片分辨率这个概念并不了解,今天就来为大家具体介绍一下图片1920x1080怎么调以及怎么给 ...

最新文章

  1. Golang中Buffer高效拼接字符串以及自定义线程安全Buffer
  2. 基於IIS的WCF的分布式多層架構開發實現
  3. 浅谈微软跨平台与MONO
  4. java commons.util_Java — CommonUtil
  5. Qt C++属性类型提供给 QML调用(五)
  6. 终极会话劫持工具SSClone
  7. oracle drop table and purge
  8. 人月神话阅读笔记(二)
  9. tomcat 如何跳转到apache_第二十期:基于tomcat部署jforum站点,并结合nginx实现动静分离...
  10. 提交信息html模板,提交留言HTML模板代码
  11. mac flutter 开发环境配置 从0到1 流程
  12. linux新建两个工作组,linux添加工作组
  13. python如何开根号求过程_python开根号实例讲解
  14. Arduino 操作BT008蓝牙串口模块
  15. 【论文笔记】Image Tampering Localization Using a Dense Fully Convolutional Network
  16. 嵌入Quicktime
  17. eclipse mars2汉化包下载
  18. 一种基于陀螺仪传感器的准确计步器算法
  19. 利用range表单元素实现调色板
  20. [转载] 苹果 AppStore 应用商店生存之道

热门文章

  1. 提高自己社会竞争力的书籍
  2. Android10 mockLocation 模拟定位
  3. 全国DNS服务器ip地址
  4. php 上传图片后反转,PHP想象将图像从CMYK转换为RGB反转图像
  5. 快速刷微信小程序访问量和浏览量
  6. 第四章-整合管理【核心词:批准】
  7. 我在淘宝做前端的这三年 — 第三年
  8. Flask渲染Jinja2模板
  9. 吴恩达机器学习系列内容汇总
  10. 微信小游戏是个人尝试做游戏最好的选择