diff --git a/src/core/helpers/hidpi.js b/src/core/helpers/hidpi.js index 1892f2f75f75b279b3dc27f05ff32663d2c3eef8..f7bd0f6e5694c2a69598a655969505be8fdf8b4d 100644 --- a/src/core/helpers/hidpi.js +++ b/src/core/helpers/hidpi.js @@ -158,9 +158,7 @@ if (pixelRatio !== 1) { } export function wrapper (canvas) { - canvas.style.height = canvas.height + 'px' - canvas.style.width = canvas.width + 'px' - canvas.width *= pixelRatio - canvas.height *= pixelRatio + canvas.width = canvas.offsetWidth * pixelRatio + canvas.height = canvas.offsetHeight * pixelRatio canvas.getContext('2d').__hidpi__ = true } diff --git a/src/core/view/components/canvas/index.vue b/src/core/view/components/canvas/index.vue index a5babc476675dfcd638dbf5eda64f7879d389d12..9f7c357f0eb7b8298db5e2b0b594db6e0f62b5b8 100644 --- a/src/core/view/components/canvas/index.vue +++ b/src/core/view/components/canvas/index.vue @@ -21,6 +21,7 @@ import { } from 'uni-mixins' import { + pixelRatio, wrapper } from 'uni-helpers/hidpi' @@ -106,16 +107,8 @@ export default { method(data) } }, - _resize ({ - width, - height - }) { - var canvas = this.$refs.canvas - if (canvas.style.width !== (width + 'px') || canvas.style.height !== (height + 'px')) { - canvas.width = width - canvas.height = height - wrapper(canvas) - } + _resize () { + wrapper(this.$refs.canvas) }, _touchmove (event) { event.preventDefault() @@ -381,22 +374,44 @@ export default { } }, getImageData ({ - x, - y, + x = 0, + y = 0, width, height, + destWidth, + destHeight, + hidpi = true, callbackId }) { var imgData var canvas = this.$refs.canvas if (!width) { - width = canvas.width + width = canvas.offsetWidth - x } if (!height) { - height = canvas.height + height = canvas.offsetHeight - y } try { - imgData = canvas.getContext('2d').getImageData(x, y, width, height) + const newCanvas = document.createElement('canvas') + if (!hidpi) { + if (!destWidth && !destHeight) { + destWidth = Math.round(width * pixelRatio) + destHeight = Math.round(height * pixelRatio) + } else if (!destWidth) { + destWidth = Math.round(width / height * destHeight) + } else if (!destHeight) { + destHeight = Math.round(height / width * destWidth) + } + } else { + destWidth = width + destHeight = height + } + newCanvas.width = destWidth + newCanvas.height = destHeight + const context = newCanvas.getContext('2d') + context.__hidpi__ = true + context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false) + imgData = context.getImageData(0, 0, destWidth, destHeight) } catch (error) { UniViewJSBridge.publishHandler('onCanvasMethodCallback', { callbackId, @@ -411,8 +426,8 @@ export default { data: { errMsg: 'canvasGetImageData:ok', data: [...imgData.data], - width, - height + width: destWidth, + height: destHeight } }, this.$page.id) }, @@ -428,8 +443,12 @@ export default { if (!height) { height = Math.round(data.length / 4 / width) } - this.$refs.canvas.getContext('2d').putImageData(new ImageData(new Uint8ClampedArray(data), width, - height), x, y) + const canvas = document.createElement('canvas') + canvas.width = width + canvas.height = height + const context = canvas.getContext('2d') + context.putImageData(new ImageData(new Uint8ClampedArray(data), width, height), 0, 0) + this.$refs.canvas.getContext('2d').drawImage(canvas, x, y, width, height) } catch (error) { UniViewJSBridge.publishHandler('onCanvasMethodCallback', { callbackId, diff --git a/src/platforms/h5/service/api/context/canvas.js b/src/platforms/h5/service/api/context/canvas.js index 914708d75c3ef2f95be156c825c976327eb6f6e7..03265b51f78371777028ee6d42b60de3f1863ae4 100644 --- a/src/platforms/h5/service/api/context/canvas.js +++ b/src/platforms/h5/service/api/context/canvas.js @@ -1,5 +1,4 @@ import createCallbacks from 'uni-helpers/callbacks' -import { pixelRatio } from 'uni-helpers/hidpi' const canvasEventCallbacks = createCallbacks('canvasEvent') @@ -808,8 +807,8 @@ export function canvasPutImageData ({ } export function canvasToTempFilePath ({ - x, - y, + x = 0, + y = 0, width, height, destWidth, @@ -818,13 +817,7 @@ export function canvasToTempFilePath ({ fileType, qualit }, callbackId) { - if (typeof width !== 'undefined') { - width *= pixelRatio - } - if (typeof height !== 'undefined') { - height *= pixelRatio - } - var pageId + let pageId const app = getApp() if (app.$route && app.$route.params.__id__) { pageId = app.$route.params.__id__ @@ -834,37 +827,39 @@ export function canvasToTempFilePath ({ }) return } - var cId = canvasEventCallbacks.push(function (data) { - var imgData = data.data - if (!imgData || !imgData.length) { + const cId = canvasEventCallbacks.push(function ({ + data, + width, + height + }) { + if (!data || !data.length) { invoke(callbackId, { errMsg: 'canvasToTempFilePath:fail' }) return } + let imgData try { - imgData = new ImageData(new Uint8ClampedArray(imgData), data.width, data.height) + imgData = new ImageData(new Uint8ClampedArray(data), width, height) } catch (error) { invoke(callbackId, { errMsg: 'canvasToTempFilePath:fail' }) return } - var canvas = getTempCanvas() - canvas.width = data.width - canvas.height = data.height - var c2d = canvas.getContext('2d') + const canvas = getTempCanvas() + canvas.width = width + canvas.height = height + const c2d = canvas.getContext('2d') c2d.putImageData(imgData, 0, 0) - var base64 = canvas.toDataURL('image/png') - var img = new Image() + let base64 = canvas.toDataURL('image/png') + const img = new Image() img.onload = function () { - var width = canvas.width = typeof destWidth === 'number' ? destWidth : imgData.width * pixelRatio - var height = canvas.height = typeof destHeight === 'number' ? destHeight : imgData.height * pixelRatio if (fileType === 'jpeg') { c2d.fillStyle = '#fff' - c2d.fillRect(0, 0, width, height) + c2d.fillRect(0, 0, width, width) } - c2d.drawImage(img, 0, 0, img.width, img.height, 0, 0, width, height) + c2d.drawImage(img, 0, 0) base64 = canvas.toDataURL(`image/${fileType}`, qualit) invoke(callbackId, { errMsg: 'canvasToTempFilePath:ok', @@ -878,6 +873,9 @@ export function canvasToTempFilePath ({ y, width, height, + destWidth, + destHeight, + hidpi: false, callbackId: cId }) }