Commit e6ed9f7f authored by Kuo Jen Wei's avatar Kuo Jen Wei Committed by Commit Bot

CCA: Replace create canvas with util.newDrawingCanvas()

Replace will createElement('canvas') call with new
util.newDrawingCanvas() function with good typed return value.

Bug: 1122444
Test: tast run <DUT> "camera.CCAUI*"

Change-Id: I7c9f994fdbeec6b6f49b3039be032c578c37099b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2379348
Commit-Queue: Inker Kuo <inker@chromium.org>
Auto-Submit: Inker Kuo <inker@chromium.org>
Reviewed-by: default avatarShik Chen <shik@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802888}
parent c971d1ee
...@@ -3,11 +3,28 @@ ...@@ -3,11 +3,28 @@
// found in the LICENSE file. // found in the LICENSE file.
import {browserProxy} from './browser_proxy/browser_proxy.js'; import {browserProxy} from './browser_proxy/browser_proxy.js';
import {assertInstanceof} from './chrome_util.js';
import {ErrorLevel, ErrorType, reportError} from './error.js'; import {ErrorLevel, ErrorType, reportError} from './error.js';
import * as state from './state.js'; import * as state from './state.js';
import * as tooltip from './tooltip.js'; import * as tooltip from './tooltip.js';
import {Facing} from './type.js'; import {Facing} from './type.js';
/**
* Creates a canvas element for 2D drawing.
* @param {{width: number, height: number}} params Width/Height of the canvas.
* @return {{canvas: !HTMLCanvasElement, ctx: !CanvasRenderingContext2D}}
* Returns canvas element and the context for 2D drawing.
*/
export function newDrawingCanvas({width, height}) {
const canvas =
assertInstanceof(document.createElement('canvas'), HTMLCanvasElement);
canvas.width = width;
canvas.height = height;
const ctx =
assertInstanceof(canvas.getContext('2d'), CanvasRenderingContext2D);
return {canvas, ctx};
}
/** /**
* Gets the clockwise rotation and flip that can orient a photo to its upright * Gets the clockwise rotation and flip that can orient a photo to its upright
* position of the photo and drop its orientation information. * position of the photo and drop its orientation information.
...@@ -98,41 +115,38 @@ export function orientPhoto(blob, onSuccess, onFailure) { ...@@ -98,41 +115,38 @@ export function orientPhoto(blob, onSuccess, onFailure) {
// TODO(shenghao): Revise or remove this function if it's no longer // TODO(shenghao): Revise or remove this function if it's no longer
// applicable. // applicable.
const drawPhoto = function(original, orientation, onSuccess, onFailure) { const drawPhoto = function(original, orientation, onSuccess, onFailure) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const canvasSquareLength = Math.max(original.width, original.height); const canvasSquareLength = Math.max(original.width, original.height);
canvas.width = canvasSquareLength; const {canvas, ctx} = newDrawingCanvas(
canvas.height = canvasSquareLength; {width: canvasSquareLength, height: canvasSquareLength});
const [centerX, centerY] = [canvas.width / 2, canvas.height / 2]; const [centerX, centerY] = [canvas.width / 2, canvas.height / 2];
context.translate(centerX, centerY); ctx.translate(centerX, centerY);
context.rotate(orientation.rotation * Math.PI / 180); ctx.rotate(orientation.rotation * Math.PI / 180);
if (orientation.flip) { if (orientation.flip) {
context.scale(-1, 1); ctx.scale(-1, 1);
} }
context.drawImage( ctx.drawImage(
original, -original.width / 2, -original.height / 2, original.width, original, -original.width / 2, -original.height / 2, original.width,
original.height); original.height);
if (orientation.flip) { if (orientation.flip) {
context.scale(-1, 1); ctx.scale(-1, 1);
} }
context.rotate(-orientation.rotation * Math.PI / 180); ctx.rotate(-orientation.rotation * Math.PI / 180);
context.translate(-centerX, -centerY); ctx.translate(-centerX, -centerY);
const outputCanvas = document.createElement('canvas'); const outputSize = (() => {
if (orientation.rotation === 90 || orientation.rotation === 270) { if (orientation.rotation === 90 || orientation.rotation === 270) {
outputCanvas.width = original.height; return {width: original.height, height: original.width};
outputCanvas.height = original.width; } else {
} else { return {width: original.width, height: original.height};
outputCanvas.width = original.width; }
outputCanvas.height = original.height; })();
} const {canvas: outputCanvas, ctx: outputCtx} = newDrawingCanvas(outputSize);
const imageData = context.getImageData( const imageData = ctx.getImageData(
(canvasSquareLength - outputCanvas.width) / 2, (canvasSquareLength - outputCanvas.width) / 2,
(canvasSquareLength - outputCanvas.height) / 2, outputCanvas.width, (canvasSquareLength - outputCanvas.height) / 2, outputCanvas.width,
outputCanvas.height); outputCanvas.height);
const outputContext = outputCanvas.getContext('2d'); outputCtx.putImageData(imageData, 0, 0);
outputContext.putImageData(imageData, 0, 0);
outputCanvas.toBlob(function(blob) { outputCanvas.toBlob(function(blob) {
if (blob) { if (blob) {
...@@ -147,7 +161,8 @@ export function orientPhoto(blob, onSuccess, onFailure) { ...@@ -147,7 +161,8 @@ export function orientPhoto(blob, onSuccess, onFailure) {
if (orientation.rotation === 0 && !orientation.flip) { if (orientation.rotation === 0 && !orientation.flip) {
onSuccess(blob); onSuccess(blob);
} else { } else {
const original = document.createElement('img'); const original =
assertInstanceof(document.createElement('img'), HTMLImageElement);
original.onload = function() { original.onload = function() {
drawPhoto(original, orientation, onSuccess, onFailure); drawPhoto(original, orientation, onSuccess, onFailure);
}; };
...@@ -337,7 +352,9 @@ export function getDefaultFacing() { ...@@ -337,7 +352,9 @@ export function getDefaultFacing() {
* @return {!Promise<!Blob>} Promise for the result. * @return {!Promise<!Blob>} Promise for the result.
*/ */
export async function scalePicture(url, isVideo, width, height = undefined) { export async function scalePicture(url, isVideo, width, height = undefined) {
const element = document.createElement(isVideo ? 'video' : 'img'); const element =
/** @type {(!HTMLImageElement|!HTMLVideoElement)} */ (
document.createElement(isVideo ? 'video' : 'img'));
if (isVideo) { if (isVideo) {
element.preload = 'auto'; element.preload = 'auto';
} }
...@@ -346,21 +363,18 @@ export async function scalePicture(url, isVideo, width, height = undefined) { ...@@ -346,21 +363,18 @@ export async function scalePicture(url, isVideo, width, height = undefined) {
element.addEventListener('error', reject); element.addEventListener('error', reject);
element.src = url; element.src = url;
}); });
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
if (height === undefined) { if (height === undefined) {
const ratio = isVideo ? element.videoHeight / element.videoWidth : const ratio = isVideo ? element.videoHeight / element.videoWidth :
element.height / element.width; element.height / element.width;
height = Math.round(width * ratio); height = Math.round(width * ratio);
} }
canvas.width = width; const {canvas, ctx} = newDrawingCanvas({width, height});
canvas.height = height; ctx.drawImage(element, 0, 0, width, height);
context.drawImage(element, 0, 0, width, height);
/** /**
* @type {!Uint8ClampedArray} A one-dimensional pixels array in RGBA order. * @type {!Uint8ClampedArray} A one-dimensional pixels array in RGBA order.
*/ */
const data = context.getImageData(0, 0, width, height).data; const data = ctx.getImageData(0, 0, width, height).data;
if (data.every((byte) => byte === 0)) { if (data.every((byte) => byte === 0)) {
reportError( reportError(
ErrorType.BROKEN_THUMBNAIL, ErrorLevel.ERROR, ErrorType.BROKEN_THUMBNAIL, ErrorLevel.ERROR,
......
...@@ -21,10 +21,7 @@ import { ...@@ -21,10 +21,7 @@ import {
async function cropSquare(blob) { async function cropSquare(blob) {
const img = await util.blobToImage(blob); const img = await util.blobToImage(blob);
const side = Math.min(img.width, img.height); const side = Math.min(img.width, img.height);
const canvas = document.createElement('canvas'); const {canvas, ctx} = util.newDrawingCanvas({width: side, height: side});
canvas.width = side;
canvas.height = side;
const ctx = canvas.getContext('2d');
ctx.drawImage( ctx.drawImage(
img, Math.floor((img.width - side) / 2), img, Math.floor((img.width - side) / 2),
Math.floor((img.height - side) / 2), side, side, 0, 0, side, side); Math.floor((img.height - side) / 2), side, side, 0, 0, side, side);
......
...@@ -7,6 +7,7 @@ import {assertInstanceof} from '../../chrome_util.js'; ...@@ -7,6 +7,7 @@ import {assertInstanceof} from '../../chrome_util.js';
import {DeviceOperator, parseMetadata} from '../../mojo/device_operator.js'; import {DeviceOperator, parseMetadata} from '../../mojo/device_operator.js';
import * as nav from '../../nav.js'; import * as nav from '../../nav.js';
import * as state from '../../state.js'; import * as state from '../../state.js';
import * as util from '../../util.js';
/** /**
* Creates a controller for the video preview of Camera view. * Creates a controller for the video preview of Camera view.
...@@ -200,10 +201,8 @@ export class Preview { ...@@ -200,10 +201,8 @@ export class Preview {
* @return {!Promise<!Blob>} Promise for the result. * @return {!Promise<!Blob>} Promise for the result.
*/ */
toImage() { toImage() {
const canvas = document.createElement('canvas'); const {canvas, ctx} = util.newDrawingCanvas(
const ctx = canvas.getContext('2d'); {width: this.video_.videoWidth, height: this.video_.videoHeight});
canvas.width = this.video_.videoWidth;
canvas.height = this.video_.videoHeight;
ctx.drawImage(this.video_, 0, 0); ctx.drawImage(this.video_, 0, 0);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
canvas.toBlob((blob) => { canvas.toBlob((blob) => {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment