Files
filament/test/renderdiff/src/viewer_html/tiff-viewer.js
Powei Feng a36ad004b7 renderdiff: add ability to diff arbitrary rendered images (#9211)
Add a way to show the difference between two rendererd image.
This is a convenience feature to see the differences between
backends.

Refactor the ExpandedFailedResult to use this new view.
2025-09-16 00:27:42 +00:00

108 lines
3.1 KiB
JavaScript

// Copyright (C) 2025 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { LitElement, html, css } from "https://cdn.jsdelivr.net/gh/lit/dist@3/all/lit-all.min.js";
// Generated by Gemini with some modifications
export class TiffViewer extends LitElement {
static styles = css`
:host {
display: block;
}
canvas {
border: 1px solid #ccc;
width: 100%;
height: 100%;
}
`;
static properties = {
fileurl: {type: String, attribute: 'fileurl'},
name: {type: String, attribute: 'name'},
};
constructor() {
super();
this.fileurl = null;
this.name = null;
}
render() {
return html`<canvas id="tiffCanvas"></canvas>`;
}
updated(props) {
if (props.has('fileurl') && this.fileurl) {
this._updateImage(this.fileurl);
}
}
async _updateImage(fileurl) {
const fileblob = await ((await fetch(this.fileurl)).arrayBuffer());
const canvas = this.shadowRoot.getElementById('tiffCanvas');
const ctx = canvas.getContext('2d');
try {
const arrayBuffer = fileblob;
const ifds = UTIF.decode(arrayBuffer); // Parse TIFF data
if (!ifds || ifds.length === 0) {
console.error('Could not decode TIFF file. No image data found.');
this._clearCanvas();
return;
}
// By default, render the first image in the TIFF (IFD)
const firstImage = ifds[0];
UTIF.decodeImage(arrayBuffer, firstImage, ifds); // Decode the actual pixel data
const rgba = UTIF.toRGBA8(firstImage); // Convert to RGBA
canvas.width = firstImage.width;
canvas.height = firstImage.height;
// The default mode would set alpha to 1 so that RGB differences would be displayed as non-transparent
for (let i = 0; i < firstImage.width; i++) {
for (let j = 0; j < firstImage.height; j++) {
rgba[(j * firstImage.width * 4) + (i * 4) + 3] = 255;
}
}
const imageData = new ImageData(new Uint8ClampedArray(rgba), firstImage.width, firstImage.height);
ctx.putImageData(imageData, 0, 0);
this.dispatchEvent(new CustomEvent('image-loaded', {
bubbles: true,
composed: true,
detail: {
name: this.name,
img: imageData,
}
}));
} catch (error) {
console.error('Error processing TIFF file:', error);
this._clearCanvas();
}
}
_clearCanvas() {
const canvas = this.shadowRoot.getElementById('tiffCanvas');
if (canvas) {
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
}
customElements.define('tiff-viewer', TiffViewer);