无法渲染 TIFF 图像并将其添加为织物对象
Unable to render TIFF images and add it as a Fabric Object
我已阅读教程:http://fabricjs.com/articles 和有关 Fabric 对象的文档。
我能够加载 JPG 和 PNG 图像,但在我的项目中,我需要将 TIFF 图像加载到 canvas 上并能够对其应用滤镜。我可以使用 canvas 上下文渲染 TIFF 图像,但每当调用 'renderAll()' 时,它都会清除上下文,我的 TIFF 图像也会被清除。我也无法执行其他操作,如缩放、平移、亮度和对比度,因为我无法渲染它。
有人可以帮助我了解如何将 TIFF 图像转换为 Fabric 对象,以便我可以对其执行所有标准 fabric.Object 相关操作。
以下是我遵循的步骤:
要加载模拟 TIFF 图像,我将其作为数组缓冲区读取。
public loadMockTiffImage() {
// Create a new XMLHttpRequest object to read the mock TIFF image as ArrayBuffer
const xhr = new XMLHttpRequest();
// Configure it: GET-request for the URL
xhr.open('GET', 'assets/tif/sample.tif', true);
xhr.responseType = 'arraybuffer';
xhr.timeout = 10000; // timeout in ms, 10 seconds
// Send the request over the network
xhr.send();
// After the response is received, load it
xhr.onload = () => {
// analyze HTTP status of the response
if (xhr.status !== 200) {
// throw error incase status is not 200
console.log(`Error ${xhr.status}: ${xhr.statusText}`);
} else {
// Show the result
console.log(`Done, got ${xhr.response.byteLength} bytes`);
console.log(xhr.response);
// Add to canvas the XHR response which is of type ArrayBuffer
this.addTiffImageOnCanvas(xhr.response);
}
};
// Show progress of loading the bytes
xhr.onprogress = event => {
if (event.lengthComputable) {
console.log(`Received ${event.loaded} of ${event.total} bytes`);
} else {
console.log(`Received ${event.loaded} bytes`); // no Content-Length
}
};
// Log any network request errors
xhr.onerror = () => {
console.log('Request failed!');
};
}
接下来,我使用 UTIF.js 解码 ArrayBuffer 并将其转换为 ImageBitmap,以便我可以使用 canvas.drawImage() 将其渲染到 canvas 上。 如何将此 ImageBitmap/ArrayBuffer 转换为 FabricJS 对象?
private addTiffImageOnCanvas(buffer: ArrayBuffer) {
// Using UTIF.js to decode the array buffer and convert it to ImageBitmap
const ifds = UTIF.decode(buffer);
UTIF.decodeImage(buffer, ifds[0]);
const timage = ifds[0];
const array = new Uint8ClampedArray(UTIF.toRGBA8(timage));
// Forming image Data
const imageData = new ImageData(array, timage.width, timage.height);
let ibm: ImageBitmap = null;
const bmPromise: Promise<ImageBitmap> = createImageBitmap(imageData);
bmPromise.then(bitmap => {
ibm = bitmap;
fabric.Image.fromObject(ibm, image => {
// TODO: How or What should I do now?
});
});
}
感谢您的帮助。
我没有在 fabric 的 github 仓库中找到任何能够处理 ImageBitmap 的内容。
但是,您可以很好地从 HTMLCanvasElement 创建 Fabric.Image。
因此,您必须在 canvas 上绘制此 ImageBitmap,如果我们无论如何要使用 canvas,最好在上一步完成,当您获得 ImageData:
var scene = new fabric.Canvas('fabric');
scene.setHeight(500);
scene.setWidth(500);
fetch( "https://upload.wikimedia.org/wikipedia/commons/d/d8/Example.tiff" )
.then( (resp) => resp.arrayBuffer() )
.then( makeFabricImageFromTiff )
.then( (fabricImage) => scene.add( fabricImage ) );
function makeFabricImageFromTiff( buffer ) {
// Using UTIF.js to decode the array buffer and convert it to ImageData
const ifds = UTIF.decode( buffer );
UTIF.decodeImage( buffer, ifds[ 0 ] );
const timage = ifds[ 0 ];
const array = new Uint8ClampedArray( UTIF.toRGBA8( timage ) );
// Forming image Data
const imageData = new ImageData( array, timage.width, timage.height );
// a temporary canvas element
const canvas = document.createElement( 'canvas' );
canvas.width = timage.width;
canvas.height = timage.height;
// on which we draw the ImageData
canvas.getContext( '2d' )
.putImageData( imageData, 0, 0 );
// before converting it to a Fabric.Image instance
return new fabric.Image( canvas, { left: 50, top: 50 } );
}
canvas { border: 1px solid; }
<script src="https://cdn.jsdelivr.net/gh/photopea/UTIF.js/UTIF.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.4/fabric.min.js"></script>
<canvas id="fabric"></canvas>
我已阅读教程:http://fabricjs.com/articles 和有关 Fabric 对象的文档。
我能够加载 JPG 和 PNG 图像,但在我的项目中,我需要将 TIFF 图像加载到 canvas 上并能够对其应用滤镜。我可以使用 canvas 上下文渲染 TIFF 图像,但每当调用 'renderAll()' 时,它都会清除上下文,我的 TIFF 图像也会被清除。我也无法执行其他操作,如缩放、平移、亮度和对比度,因为我无法渲染它。
有人可以帮助我了解如何将 TIFF 图像转换为 Fabric 对象,以便我可以对其执行所有标准 fabric.Object 相关操作。
以下是我遵循的步骤:
要加载模拟 TIFF 图像,我将其作为数组缓冲区读取。
public loadMockTiffImage() { // Create a new XMLHttpRequest object to read the mock TIFF image as ArrayBuffer const xhr = new XMLHttpRequest(); // Configure it: GET-request for the URL xhr.open('GET', 'assets/tif/sample.tif', true); xhr.responseType = 'arraybuffer'; xhr.timeout = 10000; // timeout in ms, 10 seconds // Send the request over the network xhr.send(); // After the response is received, load it xhr.onload = () => { // analyze HTTP status of the response if (xhr.status !== 200) { // throw error incase status is not 200 console.log(`Error ${xhr.status}: ${xhr.statusText}`); } else { // Show the result console.log(`Done, got ${xhr.response.byteLength} bytes`); console.log(xhr.response); // Add to canvas the XHR response which is of type ArrayBuffer this.addTiffImageOnCanvas(xhr.response); } }; // Show progress of loading the bytes xhr.onprogress = event => { if (event.lengthComputable) { console.log(`Received ${event.loaded} of ${event.total} bytes`); } else { console.log(`Received ${event.loaded} bytes`); // no Content-Length } }; // Log any network request errors xhr.onerror = () => { console.log('Request failed!'); }; }
接下来,我使用 UTIF.js 解码 ArrayBuffer 并将其转换为 ImageBitmap,以便我可以使用 canvas.drawImage() 将其渲染到 canvas 上。 如何将此 ImageBitmap/ArrayBuffer 转换为 FabricJS 对象?
private addTiffImageOnCanvas(buffer: ArrayBuffer) { // Using UTIF.js to decode the array buffer and convert it to ImageBitmap const ifds = UTIF.decode(buffer); UTIF.decodeImage(buffer, ifds[0]); const timage = ifds[0]; const array = new Uint8ClampedArray(UTIF.toRGBA8(timage)); // Forming image Data const imageData = new ImageData(array, timage.width, timage.height); let ibm: ImageBitmap = null; const bmPromise: Promise<ImageBitmap> = createImageBitmap(imageData); bmPromise.then(bitmap => { ibm = bitmap; fabric.Image.fromObject(ibm, image => { // TODO: How or What should I do now? }); });
}
感谢您的帮助。
我没有在 fabric 的 github 仓库中找到任何能够处理 ImageBitmap 的内容。
但是,您可以很好地从 HTMLCanvasElement 创建 Fabric.Image。 因此,您必须在 canvas 上绘制此 ImageBitmap,如果我们无论如何要使用 canvas,最好在上一步完成,当您获得 ImageData:
var scene = new fabric.Canvas('fabric');
scene.setHeight(500);
scene.setWidth(500);
fetch( "https://upload.wikimedia.org/wikipedia/commons/d/d8/Example.tiff" )
.then( (resp) => resp.arrayBuffer() )
.then( makeFabricImageFromTiff )
.then( (fabricImage) => scene.add( fabricImage ) );
function makeFabricImageFromTiff( buffer ) {
// Using UTIF.js to decode the array buffer and convert it to ImageData
const ifds = UTIF.decode( buffer );
UTIF.decodeImage( buffer, ifds[ 0 ] );
const timage = ifds[ 0 ];
const array = new Uint8ClampedArray( UTIF.toRGBA8( timage ) );
// Forming image Data
const imageData = new ImageData( array, timage.width, timage.height );
// a temporary canvas element
const canvas = document.createElement( 'canvas' );
canvas.width = timage.width;
canvas.height = timage.height;
// on which we draw the ImageData
canvas.getContext( '2d' )
.putImageData( imageData, 0, 0 );
// before converting it to a Fabric.Image instance
return new fabric.Image( canvas, { left: 50, top: 50 } );
}
canvas { border: 1px solid; }
<script src="https://cdn.jsdelivr.net/gh/photopea/UTIF.js/UTIF.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.4/fabric.min.js"></script>
<canvas id="fabric"></canvas>