diff --git a/src/core/service/api/context/canvas.js b/src/core/service/api/context/canvas.js index 655ee60e95e19dc429e8c9f11550ef9956ac595f..47a31c3c3e51a0019869b5466c1b94e19f2c389a 100644 --- a/src/core/service/api/context/canvas.js +++ b/src/core/service/api/context/canvas.js @@ -4,7 +4,6 @@ import { import createCallbacks from 'uni-helpers/callbacks' import { - invokeMethod, getCurrentPageId } from '../../platform' @@ -12,6 +11,10 @@ import { invoke } from '../../bridge' +import { + TEMP_PATH +} from 'uni-platform/service/api/constants' + const canvasEventCallbacks = createCallbacks('canvasEvent') UniServiceJSBridge.subscribe('onDrawCanvas', ({ @@ -879,37 +882,20 @@ export function canvasToTempFilePath ({ }) return } - const cId = canvasEventCallbacks.push(function ({ - base64 - }) { - if (!base64 || !base64.length) { - invoke(callbackId, { - errMsg: 'canvasToTempFilePath:fail' - }) - } - invokeMethod('base64ToTempFilePath', { - base64Data: base64, - x, - y, - width, - height, - destWidth, - destHeight, - canvasId, - fileType, - qualit - }, callbackId) + const cId = canvasEventCallbacks.push(function (res) { + invoke(callbackId, res) }) - operateCanvas(canvasId, pageId, 'getDataUrl', { + const dirname = `${TEMP_PATH}/canvas` + operateCanvas(canvasId, pageId, 'toTempFilePath', { x, y, width, height, destWidth, destHeight, - hidpi: false, fileType, qualit, + dirname, callbackId: cId }) -} +} diff --git a/src/core/view/components/canvas/index.vue b/src/core/view/components/canvas/index.vue index f1b0ba4f7772f34d954b1f094d624e04f33e790d..08a1e638c40f39f8015ce0757150b3c41a47a2bd 100644 --- a/src/core/view/components/canvas/index.vue +++ b/src/core/view/components/canvas/index.vue @@ -28,6 +28,8 @@ import { wrapper } from 'uni-helpers/hidpi' +import saveImage from 'uni-platform/helpers/save-image' + function resolveColor (color) { color = color.slice(0) color[3] = color[3] / 255 @@ -406,10 +408,13 @@ export default { destWidth, destHeight, hidpi = true, + dataType, + qualit = 1, + type = 'png', callbackId }) { - var imgData - var canvas = this.$refs.canvas + const canvas = this.$refs.canvas + let data if (!width) { width = canvas.offsetWidth - x } @@ -432,9 +437,20 @@ export default { } const newCanvas = getTempCanvas(destWidth, destHeight) const context = newCanvas.getContext('2d') + if (type === 'jpeg' || type === 'jpg') { + type = 'jpeg' + context.fillStyle = '#fff' + context.fillRect(0, 0, destWidth, destHeight) + } context.__hidpi__ = true context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false) - imgData = context.getImageData(0, 0, destWidth, destHeight) + if (dataType === 'base64') { + data = newCanvas.toDataURL(`image/${type}`, qualit) + } else { + const imgData = context.getImageData(0, 0, destWidth, destHeight) + // fix [...]展开TypedArray在低版本手机报错的问题,使用Array.prototype.slice + data = Array.prototype.slice.call(imgData.data) + } newCanvas.height = newCanvas.width = 0 context.__hidpi__ = false } catch (error) { @@ -450,9 +466,8 @@ export default { return } if (!callbackId) { - // fix [...]展开TypedArray在低版本手机报错的问题,使用Array.prototype.slice return { - data: Array.prototype.slice.call(imgData.data), + data, width: destWidth, height: destHeight } @@ -461,7 +476,7 @@ export default { callbackId, data: { errMsg: 'canvasGetImageData:ok', - data: [...imgData.data], + data, width: destWidth, height: destHeight } @@ -501,16 +516,16 @@ export default { } }, this.$page.id) }, - getDataUrl ({ + toTempFilePath ({ x = 0, y = 0, width, height, destWidth, destHeight, - hidpi = true, fileType, qualit, + dirname, callbackId }) { const res = this.getImageData({ @@ -520,56 +535,33 @@ export default { height, destWidth, destHeight, - hidpi + hidpi: false, + dataType: 'base64', + type: fileType, + qualit }) if (!res.data || !res.data.length) { UniViewJSBridge.publishHandler('onCanvasMethodCallback', { callbackId, data: { - errMsg: 'canvasGetDataUrl:fail' - } - }, this.$page.id) - return - } - let imgData - try { - imgData = new ImageData(new Uint8ClampedArray(res.data), res.width, res.height) - } catch (error) { - UniViewJSBridge.publishHandler('onCanvasMethodCallback', { - callbackId, - data: { - errMsg: 'canvasGetDataUrl:fail' + errMsg: 'toTempFilePath:fail' } }, this.$page.id) return } - destWidth = res.width - destHeight = res.height - const canvas = getTempCanvas(destWidth, destHeight) - const c2d = canvas.getContext('2d') - c2d.putImageData(imgData, 0, 0) - let base64 = canvas.toDataURL('image/png') - canvas.height = canvas.width = 0 - const img = new Image() - img.onload = () => { - const canvas = getTempCanvas(destWidth, destHeight) - if (fileType === 'jpeg' || fileType === 'jpg') { - fileType = 'jpeg' - c2d.fillStyle = '#fff' - c2d.fillRect(0, 0, destWidth, destHeight) + saveImage(res.data, dirname, (error, tempFilePath) => { + let errMsg = `toTempFilePath:${error ? 'fail' : 'ok'}` + if (error) { + errMsg += ` ${error.message}` } - c2d.drawImage(img, 0, 0) - base64 = canvas.toDataURL(`image/${fileType}`, qualit) - canvas.height = canvas.width = 0 UniViewJSBridge.publishHandler('onCanvasMethodCallback', { callbackId, data: { - errMsg: 'canvasGetDataUrl:ok', - base64: base64 + errMsg, + tempFilePath: tempFilePath } }, this.$page.id) - } - img.src = base64 + }) } } } diff --git a/src/platforms/app-plus/helpers/save-image.js b/src/platforms/app-plus/helpers/save-image.js new file mode 100644 index 0000000000000000000000000000000000000000..057eeeb9e045262d7f98c4bdf9ad9f7d3c138f60 --- /dev/null +++ b/src/platforms/app-plus/helpers/save-image.js @@ -0,0 +1,28 @@ +let index = 0 + +export default function saveImage (base64, dirname, callback) { + const id = `${Date.now()}${index++}` + const bitmap = new plus.nativeObj.Bitmap(`bitmap${id}`) + bitmap.loadBase64Data(base64, function () { + const format = (base64.match(/data:image\/(\S+?);/) || [null, 'png'])[1].replace('jpeg', 'jpg') + const tempFilePath = `${dirname}/${id}.${format}` + bitmap.save(tempFilePath, { + overwrite: true, + quality: 100, + format + }, function () { + clear() + callback(null, tempFilePath) + }, function (error) { + clear() + callback(error) + }) + }, function (error) { + clear() + callback(error) + }) + + function clear () { + bitmap.clear() + } +} diff --git a/src/platforms/app-plus/service/api/context/canvas.js b/src/platforms/app-plus/service/api/context/canvas.js deleted file mode 100644 index fe696eb43b1e799479f70a2beaf0f23c865ff877..0000000000000000000000000000000000000000 --- a/src/platforms/app-plus/service/api/context/canvas.js +++ /dev/null @@ -1,78 +0,0 @@ -import { - invoke -} from '../../bridge' - -import { - TEMP_PATH -} from '../constants' - -/** - * 5+错误对象转换为错误消息 - * @param {*} error 5+错误对象 - */ -function toErrMsg (error) { - var msg = 'base64ToTempFilePath:fail' - if (error && error.message) { - msg += ` ${error.message}` - } else if (error) { - msg += ` ${error}` - } - return msg -} - -export function base64ToTempFilePath ({ - base64Data, - x, - y, - width, - height, - destWidth, - destHeight, - canvasId, - fileType, - quality -} = {}, callbackId) { - var id = Date.now() - var bitmap = new plus.nativeObj.Bitmap(`bitmap${id}`) - bitmap.loadBase64Data(base64Data, function () { - var formats = ['jpg', 'png'] - var format = String(fileType).toLowerCase() - if (formats.indexOf(format) < 0) { - format = 'png' - } - /** - * 保存配置 - */ - var saveOption = { - overwrite: true, - quality: typeof quality === 'number' ? quality * 100 : 100, - format - } - /** - * 保存文件路径 - */ - var tempFilePath = `${TEMP_PATH}/canvas/${id}.${format}` - - bitmap.save(tempFilePath, saveOption, function () { - clear() - invoke(callbackId, { - tempFilePath, - errMsg: 'base64ToTempFilePath:ok' - }) - }, function (error) { - clear() - invoke(callbackId, { - errMsg: toErrMsg(error) - }) - }) - }, function (error) { - clear() - invoke(callbackId, { - errMsg: toErrMsg(error) - }) - }) - - function clear () { - bitmap.clear() - } -} diff --git a/src/platforms/app-plus/service/api/index.js b/src/platforms/app-plus/service/api/index.js index 497fd192cfc409f4845e8b3f8b79b48ca6eea41c..f48708576482e174103663aeb77c16ffcc7c5b86 100644 --- a/src/platforms/app-plus/service/api/index.js +++ b/src/platforms/app-plus/service/api/index.js @@ -1,7 +1,6 @@ export * from './base/event-bus' export * from './context/inner-audio' export * from './context/background-audio' -export * from './context/canvas' export * from './context/operate-map-player' export * from './context/operate-video-player' export * from './context/live-pusher' diff --git a/src/platforms/h5/helpers/save-image.js b/src/platforms/h5/helpers/save-image.js new file mode 100644 index 0000000000000000000000000000000000000000..720e7bb215fd94a7162b473be07f8870730a791a --- /dev/null +++ b/src/platforms/h5/helpers/save-image.js @@ -0,0 +1,3 @@ +export default function saveImage (base64, dirname, callback) { + callback(null, base64) +} diff --git a/src/platforms/h5/service/api/constants.js b/src/platforms/h5/service/api/constants.js new file mode 100644 index 0000000000000000000000000000000000000000..14225177d3c639dcd3adf93c4789ad5908208942 --- /dev/null +++ b/src/platforms/h5/service/api/constants.js @@ -0,0 +1 @@ +export const TEMP_PATH = '' diff --git a/src/platforms/h5/service/api/context/canvas.js b/src/platforms/h5/service/api/context/canvas.js deleted file mode 100644 index 1c3f5c7842e168647f89ffdb1219624802817bbf..0000000000000000000000000000000000000000 --- a/src/platforms/h5/service/api/context/canvas.js +++ /dev/null @@ -1,21 +0,0 @@ -const { - invokeCallbackHandler: invoke -} = UniServiceJSBridge - -export function base64ToTempFilePath ({ - base64Data, - x, - y, - width, - height, - destWidth, - destHeight, - canvasId, - fileType, - quality -} = {}, callbackId) { - invoke(callbackId, { - errMsg: 'canvasToTempFilePath:ok', - tempFilePath: base64Data - }) -}