Commit 0241e119 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

CrOS Gallery: Workaround new treatment of EXIF orientation in m81.

The Chrome OS Gallery is affected badly by Blink's new treatment of
EXIF orientation for <img> and <canvas> elements. With crrev.com/741635
(and crrev.com/725393), it's now necessary to add the "new Image()", and
the <canvas> element it is drawn into, to the page temporarily.
Without this, <img> and <canvas> elements attempt to respect any EXIF
orientation in the source bitmap. This conflicts with logic in
Gallery to support the earlier behavior of these elements.

This CL sets attributes to disable the new treatment, and performs the
necessary DOM machinations to ensure these attributes take effect.

The approach should be robust enough to function as expected whether
or not the new EXIF orientation treatment is actually taking effect.

Skip presubmit: A linter complains about changes outside the scope
of this CL. (OWNERS approval still sought).

No-Presubmit: true
Bug: 1043561
Change-Id: Ib58c8bed9dd5589e3908a8336b4446eeb523170a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2065688
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743438}
parent 70a2e4eb
......@@ -31,6 +31,14 @@ ImageUtil.ImageLoader = function(document, metadataModel) {
*/
this.timeout_ = 0;
/**
* Cleanup function for Blink EXIF changes in m81. See comments in
* convertImage_() and https://crbug.com/1043561.
*
* @type {function()}
*/
this.onCancelForExifWorkaround_ = () => {};
/**
* @type {?function(!HTMLCanvasElement, string=)}
* @private
......@@ -245,6 +253,7 @@ ImageUtil.ImageLoader.prototype.cancel = function() {
}
this.callback_ = null;
if (this.timeout_) {
this.onCancelForExifWorkaround_();
clearTimeout(this.timeout_);
this.timeout_ = 0;
}
......@@ -265,6 +274,17 @@ ImageUtil.ImageLoader.prototype.convertImage_ = function(image, transform) {
this.callback_ = null;
return;
}
// Helper to suppress JSC_USELESS_CODE below. Like goog.reflect.sinkValue().
function sinkValue(value) {}
// If the <img> is not in the DOM (and style calculated for it). Chrome m81+
// provides width/height that already accounts for EXIF orientations.
image.style.imageOrientation = 'none';
image.style.visibility = 'hidden';
document.body.appendChild(image);
sinkValue(image.clientWidth); // Ensure style resolves.
var canvas = this.document_.createElement('canvas');
if (transform.rotate90 & 1) { // Rotated +/-90deg, swap the dimensions.
......@@ -275,6 +295,24 @@ ImageUtil.ImageLoader.prototype.convertImage_ = function(image, transform) {
canvas.height = image.height;
}
// Before getting context, apply style to ignore EXIF orientation from source
// pixel data. The <canvas> also needs to be in the DOM when getContext() is
// called for this to take effect.
canvas.style.imageOrientation = 'none';
canvas.style.visibility = 'hidden';
document.body.appendChild(canvas);
sinkValue(canvas.clientWidth); // Ensure style resolves.
// Remove image and canvas from the DOM once the content is drawn. Note the
// canvas may be added back later. Doing this earlier causes the elements to
// "forget' their image-orientation style attribute.
this.onCancelForExifWorkaround_ = () => {
image.remove();
canvas.remove();
canvas.style.visibility = 'unset';
this.onCancelForExifWorkaround_ = () => {};
};
var context = canvas.getContext('2d');
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
......@@ -308,6 +346,7 @@ ImageUtil.ImageLoader.prototype.copyStrip_ = function(
if (this.entry_.toURL().substr(0, 5) !== 'data:') { // Ignore data urls.
metrics.recordInterval(ImageUtil.getMetricName('LoadTime'));
}
this.onCancelForExifWorkaround_();
setTimeout(this.callback_, 0, context.canvas);
this.callback_ = null;
} else {
......
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