The export of a corrupted "OffscreenCanvas" is prohibited

Currently, I am implementing a process where an ImageBitmap is passed into a web worker in order to render it on a canvas. Subsequently, a URL is generated for loading into THREE.js on the main thread.

Within the main thread

 this.canvas = this.canvasEl.transferControlToOffscreen() 
this.workerInstance.postMessage({canvas: this.canvas}, [this.canvas]);
...

createImageBitmap(this.img).then(imageData =>  {
        this.imageBitmap = imageData
        this.workerInstance.postMessage({image:imageData}, [imageData])

Inside the worker

_ctx.drawImage(image, 0, 0)
    _canvas.convertToBlob({type: "image/png"}).then(blob => console.log(blob))

Encountered a DOMException: Failed to execute 'convertToBlob' on 'OffscreenCanvas': The "OffscreenCanvas" in use may not be exported.

The image on the main thread is marked with crossorigin="anonymous". Another image is also added to it, but both are from the same domain.

This image is dynamically created:

docString = '<svg width="' + this.width + '" height="' + this.height + '" xmlns="http://www.w3.org/2000/svg"><defs><style type="text/css"><![CDATA[a[href]{color:#0000EE;text-decoration:underline;}' + this.cssembed.join('') + ']]></style></defs><foreignObject x="0" y="0" width="' + this.width + '" height="' + this.height + '">' + parent[0] + docString + parent[1] + '</foreignObject></svg>';
this.img.src = "data:image/svg+xml;utf8," + encodeURIComponent(docString);

You can view the code here.

I am currently in the process of updating the code to utilize Offscreen canvas and web workers for improved rendering performance.

Answer №1

This issue is connected to a previous bug that I addressed in detail here.

In this specific scenario, it seems that even employing the "data:URL hack-around" will not solve the problem, likely due to additional checks conducted within the internal steps of createImageBitmap.

I will make a note of this in the bug report. In the meantime, the workaround involves rasterizing the svg image on a <canvas> first and then utilizing that <canvas> as the ImageBitmap source. This method is less than ideal but should suffice for now.

if( !window.OffscreenCanvasRenderingContext2D ) {
  console.warn("Your browser doesn't support the 2D context of the OffscreenCanvas API");
}

const worker = initWorker();

const data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
  '<foreignObject width="100%" height="100%">' +
  '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
  '<em>I</em> like ' +
  '<span style="color:white; text-shadow:0 0 2px blue;">' +
  'beer</span>' +
  '</div>' +
  '</foreignObject>' +
'</svg>';
const img = new Image();
var url = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);

img.onload = function() {
  // create a new canvas just to rasterize that svg
  const canvas = document.createElement( 'canvas' );
  const ctx = canvas.getContext('2d');
  canvas.width = img.width;
  canvas.height = img.height;
  ctx.drawImage(img, 0, 0);
  // use that canvas as the source for the ImageBitmap
  createImageBitmap(canvas).then(bmp => {
    worker.postMessage( bmp, [bmp] );
  });
};

img.src = url;

function initWorker() {
  const script = `
    let canvas, ctx;
    onmessage = e => {
      if(e.data instanceof ImageBitmap) {
        ctx.drawImage( e.data, 0, 0);
        canvas.convertToBlob().then( blob => {
          self.postMessage( blob );
        });
      }
      else {
        canvas = e.data;
        ctx = canvas.getContext('2d');
      }
    };
`
  const url = URL.createObjectURL(new Blob([script], { type: "application/javascript" }));
  const worker = new Worker(url);
  worker.onmessage = e => console.log('from worker', e.data);
  const offscreen = document.getElementById('canvas').transferControlToOffscreen();
  worker.postMessage(offscreen, [offscreen]);
  return worker;
}
<canvas id="canvas"></canvas>

One aspect that still bothers me is that you should have encountered an error prior to reaching the worker thread, specifically:

Failed to execute 'postMessage' on 'Worker': Non-origin-clean ImageBitmap cannot be transferred.

I find it puzzling that your Chrome browser managed to bypass this crucial step...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering the current time and start time of today in EST can be achieved by utilizing Moment.js

Need help with creating Start and End Time stamps using Moment.js in EST: Start Time should reflect the beginning of today End Time should show the current time. This is how I have implemented it using moment.js: var time = new Date(); var startTime=D ...

Issue with jsPDF: PNG file is either incomplete or corrupted

I'm encountering an issue while attempting to pass Image data to the addImage function. I have tried downgrading the versions of jspdf and html2canvas, as well as experimenting with different ways to import the two libraries, but the problem still per ...

adding content to div is becoming less speedy

Currently, I'm developing a drawing board using only html/css/jquery and the drawing functionality is working smoothly. The approach I've taken involves capturing the mousemove events and placing a dot (div) at each point where the event occurs, ...

"Encountered a TypeError: Cannot read property 'params

I've encountered an issue with passing the id to my product page. Despite trying various solutions and searching for answers, I still can't get it to work. Below is my index.js code: import React from "react"; import {render} from &quo ...

Access Flask variable in JavaScript code

Currently working on a CTF challenge, my query is not seeking assistance in solving it, but rather pertains to syntax. The task involves retrieving the secret key from Flask server's configuration. This key is stored within the app.secret_key variable ...

Django DRF functions properly, however it returns an error when sending a response to an AJAX request

Successfully implemented an AJAX request using PUT in DRF. All functionalities are functioning correctly except for the error callback being triggered: DRF section: class ProductDataViewSet(viewsets.ViewSet): authentication_classes = [SessionAuthentic ...

Here is a list of selections that can be easily removed and have a child selection added

While this question may be a bit ambiguous, please bear with me as I explain my dilemma. I am utilizing React to develop a component that accepts an object with keys and values as a prop. Each value within the object is a list of values. This component ne ...

Utilizing Firebase login to integrate with Facebook API

My current setup involves Facebook authentication tied to login, all managed through Firebase. However, I now face the need to make an API call to Facebook using 'me/friends/' endpoint without having to send another request since I am already log ...

Acquire the <li> element when it is clicked using vanilla JavaScript

Whenever a user enters a value in an input field, my function automatically adds a <li> element to a <ul>. Additionally, the function assigns the attribute ( onclick="doneToggle" ) to the created <li>. function createListElement() { ...

"Unlock the Power of VueJS 2 with Dynamic Templates

Just starting out as a VueJS student! I created a "MainTemplate.vue", which includes a menu, footer, header... Then I decided to create another .vue file named "ComponentB.vue". Here is the content of my ComponentB.vue file: <template> <h ...

Unusual Glitch in Bootstrap 3 Dropdown Menu

I am currently developing a website using Bootstrap 3. I am encountering an issue with the navbar dropdown. When I click on the link, it changes to show "expand child menu" and "collapse child menu". To clarify, here is the image I am referring to: Initi ...

Leveraging the power of ES6, achieve recursion with requestAnimationFrame in

Lately, I've been working on creating a versatile SceneManager class that not only manages scenes but also handles rendering. class SceneManager { constructor() { this.scene = new THREE.Scene(); this.camera = new THREE.Perspectiv ...

The additional cost associated with using a React hook is called the "

Our system includes a theme context provider that passes down a theme to all child components, calculated based on the device's dimensions. We can easily access these values using the useTheme hook in any component. In addition, we have a constants f ...

Encountering an issue while trying to import the D3.js library into my React.js application

I'm having trouble with properly importing the d3.js libraries in my react.js app. I am using import * as d3 from 'd3' to import everything and store it in the d3 namespace, but I keep getting an error that says - Cannot read property ' ...

Run a PHP script that creates a PDF file using jQuery AJAX

I am currently working with a form that looks like this: <form action="tcpdf/examples/example_0611.php" method="get"> Name: <input type="text" name="name"><br> E-mail: <input type="text" name="email"><br> <input type="subm ...

Find the identifier that does not currently exist in the collection of objects

There is a situation where I have an array and an object that consists of arrays of ids, which are essentially permission objects. My goal now is to extract the ids that do not exist in the given object. Can someone assist me with devising the necessary l ...

Formik: encountering target as undefined while passing Material UI Date Picker as prop to React Component

I'm currently working on developing a component that can be reused. The idea is to pass form fields as props, but I ran into an issue when clicking on the datepicker field. The error message that pops up is: TypeError: target is undefined Any sugge ...

Set a dynamic Active Class on various divisions by utilizing their respective indexes

I have two divs with the same class. When I click on an anchor tag within one of the elements, I want to add a class to the corresponding position in the second div as well. Mirror: JSFiddle Here is the jQuery code snippet: $(document).on('click ...

Is there an official IRC channel for YUI?

Although the yui3 documentation is quite helpful, it can also be beneficial to ask unconventional questions in order to discover the best practices. Are there any gatherings or meetups for all the talented yui developers out there? ...

What is the best way to store chat messages in a React application?

My idea for a chat application using React involves saving chat messages in localStorage. Below is the code snippet that illustrates this functionality: const [textMessages, setTextMessages] = useState([]); const [textValue, setTextValue] = useState(' ...