提交 9b86bb31 编写于 作者: Q qiang

fix: 优化 App 端 uni.canvasToTempFilePath 存储效率

上级 a9507261
...@@ -4,7 +4,6 @@ import { ...@@ -4,7 +4,6 @@ import {
import createCallbacks from 'uni-helpers/callbacks' import createCallbacks from 'uni-helpers/callbacks'
import { import {
invokeMethod,
getCurrentPageId getCurrentPageId
} from '../../platform' } from '../../platform'
...@@ -12,6 +11,10 @@ import { ...@@ -12,6 +11,10 @@ import {
invoke invoke
} from '../../bridge' } from '../../bridge'
import {
TEMP_PATH
} from 'uni-platform/service/api/constants'
const canvasEventCallbacks = createCallbacks('canvasEvent') const canvasEventCallbacks = createCallbacks('canvasEvent')
UniServiceJSBridge.subscribe('onDrawCanvas', ({ UniServiceJSBridge.subscribe('onDrawCanvas', ({
...@@ -879,37 +882,20 @@ export function canvasToTempFilePath ({ ...@@ -879,37 +882,20 @@ export function canvasToTempFilePath ({
}) })
return return
} }
const cId = canvasEventCallbacks.push(function ({ const cId = canvasEventCallbacks.push(function (res) {
base64 invoke(callbackId, res)
}) {
if (!base64 || !base64.length) {
invoke(callbackId, {
errMsg: 'canvasToTempFilePath:fail'
})
}
invokeMethod('base64ToTempFilePath', {
base64Data: base64,
x,
y,
width,
height,
destWidth,
destHeight,
canvasId,
fileType,
qualit
}, callbackId)
}) })
operateCanvas(canvasId, pageId, 'getDataUrl', { const dirname = `${TEMP_PATH}/canvas`
operateCanvas(canvasId, pageId, 'toTempFilePath', {
x, x,
y, y,
width, width,
height, height,
destWidth, destWidth,
destHeight, destHeight,
hidpi: false,
fileType, fileType,
qualit, qualit,
dirname,
callbackId: cId callbackId: cId
}) })
} }
...@@ -28,6 +28,8 @@ import { ...@@ -28,6 +28,8 @@ import {
wrapper wrapper
} from 'uni-helpers/hidpi' } from 'uni-helpers/hidpi'
import saveImage from 'uni-platform/helpers/save-image'
function resolveColor (color) { function resolveColor (color) {
color = color.slice(0) color = color.slice(0)
color[3] = color[3] / 255 color[3] = color[3] / 255
...@@ -406,10 +408,13 @@ export default { ...@@ -406,10 +408,13 @@ export default {
destWidth, destWidth,
destHeight, destHeight,
hidpi = true, hidpi = true,
dataType,
qualit = 1,
type = 'png',
callbackId callbackId
}) { }) {
var imgData const canvas = this.$refs.canvas
var canvas = this.$refs.canvas let data
if (!width) { if (!width) {
width = canvas.offsetWidth - x width = canvas.offsetWidth - x
} }
...@@ -432,9 +437,20 @@ export default { ...@@ -432,9 +437,20 @@ export default {
} }
const newCanvas = getTempCanvas(destWidth, destHeight) const newCanvas = getTempCanvas(destWidth, destHeight)
const context = newCanvas.getContext('2d') 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.__hidpi__ = true
context.drawImageByCanvas(canvas, x, y, width, height, 0, 0, destWidth, destHeight, false) 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 newCanvas.height = newCanvas.width = 0
context.__hidpi__ = false context.__hidpi__ = false
} catch (error) { } catch (error) {
...@@ -450,9 +466,8 @@ export default { ...@@ -450,9 +466,8 @@ export default {
return return
} }
if (!callbackId) { if (!callbackId) {
// fix [...]展开TypedArray在低版本手机报错的问题,使用Array.prototype.slice
return { return {
data: Array.prototype.slice.call(imgData.data), data,
width: destWidth, width: destWidth,
height: destHeight height: destHeight
} }
...@@ -461,7 +476,7 @@ export default { ...@@ -461,7 +476,7 @@ export default {
callbackId, callbackId,
data: { data: {
errMsg: 'canvasGetImageData:ok', errMsg: 'canvasGetImageData:ok',
data: [...imgData.data], data,
width: destWidth, width: destWidth,
height: destHeight height: destHeight
} }
...@@ -501,16 +516,16 @@ export default { ...@@ -501,16 +516,16 @@ export default {
} }
}, this.$page.id) }, this.$page.id)
}, },
getDataUrl ({ toTempFilePath ({
x = 0, x = 0,
y = 0, y = 0,
width, width,
height, height,
destWidth, destWidth,
destHeight, destHeight,
hidpi = true,
fileType, fileType,
qualit, qualit,
dirname,
callbackId callbackId
}) { }) {
const res = this.getImageData({ const res = this.getImageData({
...@@ -520,56 +535,33 @@ export default { ...@@ -520,56 +535,33 @@ export default {
height, height,
destWidth, destWidth,
destHeight, destHeight,
hidpi hidpi: false,
dataType: 'base64',
type: fileType,
qualit
}) })
if (!res.data || !res.data.length) { if (!res.data || !res.data.length) {
UniViewJSBridge.publishHandler('onCanvasMethodCallback', { UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId, callbackId,
data: { data: {
errMsg: 'canvasGetDataUrl:fail' errMsg: 'toTempFilePath: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'
} }
}, this.$page.id) }, this.$page.id)
return return
} }
destWidth = res.width saveImage(res.data, dirname, (error, tempFilePath) => {
destHeight = res.height let errMsg = `toTempFilePath:${error ? 'fail' : 'ok'}`
const canvas = getTempCanvas(destWidth, destHeight) if (error) {
const c2d = canvas.getContext('2d') errMsg += ` ${error.message}`
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)
} }
c2d.drawImage(img, 0, 0)
base64 = canvas.toDataURL(`image/${fileType}`, qualit)
canvas.height = canvas.width = 0
UniViewJSBridge.publishHandler('onCanvasMethodCallback', { UniViewJSBridge.publishHandler('onCanvasMethodCallback', {
callbackId, callbackId,
data: { data: {
errMsg: 'canvasGetDataUrl:ok', errMsg,
base64: base64 tempFilePath: tempFilePath
} }
}, this.$page.id) }, this.$page.id)
} })
img.src = base64
} }
} }
} }
......
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()
}
}
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()
}
}
export * from './base/event-bus' export * from './base/event-bus'
export * from './context/inner-audio' export * from './context/inner-audio'
export * from './context/background-audio' export * from './context/background-audio'
export * from './context/canvas'
export * from './context/operate-map-player' export * from './context/operate-map-player'
export * from './context/operate-video-player' export * from './context/operate-video-player'
export * from './context/live-pusher' export * from './context/live-pusher'
......
export default function saveImage (base64, dirname, callback) {
callback(null, base64)
}
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
})
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册