Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
experimental fix for element-hq/element-web#2985
Browse files Browse the repository at this point in the history
needs server to support 1600x1200 thumbnails for retina large ones.
ideally need to cap maximum thumbnail size to 800x600 rather than expand to arbitrary widths.
need to check that luke's funky timeline code doesn't get confused between naturalWidth and infoWidth etc.
also need to consider whether to encode a resolution metric in the event rather than lying about resolution.
  • Loading branch information
ara4n committed Jan 14, 2019
1 parent 2a20d9d commit 577c411
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"matrix-js-sdk": "0.14.2",
"optimist": "^0.6.1",
"pako": "^1.0.5",
"png-chunks-extract": "^1.0.0",
"prop-types": "^15.5.8",
"qrcode-react": "^0.1.16",
"querystring": "^0.2.0",
Expand Down
34 changes: 31 additions & 3 deletions src/ContentMessages.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ import { _t } from './languageHandler';
const Modal = require('./Modal');

const encrypt = require("browser-encrypt-attachment");
const png_chunks_extract = require("png-chunks-extract");

// Polyfill for Canvas.toBlob API using Canvas.toDataURL
require("blueimp-canvas-to-blob");

const MAX_WIDTH = 800;
const MAX_HEIGHT = 600;

// scraped out of a macOS hidpi (5660ppm) screenshot png
// 5669 px (x-axis) , 5669 px (y-axis) , per metre
const PHYS_HIDPI = [0x00, 0x00, 0x16, 0x25, 0x00, 0x00, 0x16, 0x25, 0x01];

/**
* Create a thumbnail for a image DOM element.
Expand Down Expand Up @@ -102,10 +106,34 @@ function loadImageElement(imageFile) {
const objectUrl = URL.createObjectURL(imageFile);
img.src = objectUrl;

// check for hi-dpi PNGs and fudge display resolution as needed.
// this is mainly needed for macOS screencaps
let hidpi = false;
if (imageFile.type === "image/png") {
// in practice macOS happens to order the chunks so they fall in
// the first 0x1000 bytes (thanks to a massive ICC header).
// Thus we could slice the file down to only sniff the first 0x1000
// bytes (but this makes png_chunks_extract choke on the corrupt file)
const headers = imageFile; //.slice(0, 0x1000);
readFileAsArrayBuffer(headers).then(arrayBuffer=>{
const buffer = new Uint8Array(arrayBuffer);
const chunks = png_chunks_extract(buffer);
for (const chunk of chunks) {
if (chunk.name === 'pHYs') {
if (chunk.data.byteLength !== PHYS_HIDPI.length) return;
hidpi = chunk.data.every((val, i) => val === PHYS_HIDPI[i]);
return;
}
}
});
}

// Once ready, create a thumbnail
img.onload = function() {
URL.revokeObjectURL(objectUrl);
deferred.resolve(img);
let width = hidpi ? (img.width >> 1) : img.width;
let height = hidpi ? (img.height >> 1) : img.height;
deferred.resolve({ img, width, height });
};
img.onerror = function(e) {
deferred.reject(e);
Expand All @@ -129,8 +157,8 @@ function infoForImageFile(matrixClient, roomId, imageFile) {
}

let imageInfo;
return loadImageElement(imageFile).then(function(img) {
return createThumbnail(img, img.width, img.height, thumbnailType);
return loadImageElement(imageFile).then(function(r) {
return createThumbnail(r.img, r.width, r.height, thumbnailType);
}).then(function(result) {
imageInfo = result.info;
return uploadFile(matrixClient, roomId, result.thumbnail);
Expand Down
10 changes: 8 additions & 2 deletions src/components/views/messages/MImageBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,16 @@ export default class MImageBody extends React.Component {
// given we deliberately don't thumbnail them serverside to prevent
// billion lol attacks and similar
return this.context.matrixClient.mxcUrlToHttp(
content.info.thumbnail_url, 800, 600,
content.info.thumbnail_url,
800 * window.devicePixelRatio,
600 * window.devicePixelRatio,
);
} else {
return this.context.matrixClient.mxcUrlToHttp(content.url, 800, 600);
return this.context.matrixClient.mxcUrlToHttp(
content.url,
800 * window.devicePixelRatio,
600 * window.devicePixelRatio
);
}
}

Expand Down

0 comments on commit 577c411

Please sign in to comment.