Creating a PNG file from a Uint8Array containing RGBA data

I am currently attempting to save a screenshot of a specific area in ThreeJS to a file.

Initial attempts involved displaying the image in a new tab using:

window.open(renderer.domElement.toDataURL("image/png"));

The renderer object used has preserveDrawingBuffer set to true.

However, since this captures the entire scene, I switched to:

    var gl = renderer.getContext();
    var pixels = new Uint8Array(width * height * 4);
    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
    window.open("data:image/png;base64," + btoa(String.fromCharCode.apply(null, pixels)));

After making this change, only a grey outlined square is rendered on screen.

https://i.sstatic.net/Zk4tv.png

Answer №1

After realizing that the data was not in the right format for a PNG, a solution was devised.

    var gl = renderer.getContext();
    var pixels = new Uint8Array(width * height * 4);
    gl.readPixels(x, y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext("2d");
    var imageData = ctx.createImageData(width, height);

    for(var i = 0; i < imageData.data.length; i+=4) {
        imageData.data[i + 0] = pixels[i + 0];
        imageData.data[i + 1] = pixels[i + 1];
        imageData.data[i + 2] = pixels[i + 2];
        imageData.data[i + 3] = pixels[i + 3];
    }

    ctx.putImageData(imageData,0,0);
    window.open(canvas.toDataURL("image/png"));
    canvas.remove();

Though not the most elegant solution, it proved effective in this case.

Answer №2

To extract a small portion of an image, you can avoid using gl.readPixels by utilizing the width and height parameters in the drawImage function.

var gl = renderer.getContext();

var ctx = document.createElement('canvas').getContext("2d");

ctx.canvas.width = width;
ctx.canvas.height = height;

ctx.drawImage(gl.canvas, 0, 0, width, height, 0, 0, width, height);

window.open(ctx.canvas.toDataURL());

There are 3 different versions of the drawImage method:

  1. drawImage(image, dstX, dstY)

  2. drawImage(image, dstX, dstY, dstWidth, dstHeight)

  3. drawImage(image, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight)

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

Having difficulty retrieving the value of a variable obtained from the Google Distance Matrix function

Utilizing the Google distance matrix API to calculate the distance between two locations, I encountered an issue with global variable access. Despite changing the variable within a function, I found that I was unable to retrieve the updated value of the va ...

Currently in motion post file selection

I am currently facing an issue with a button that triggers a file selector pop-up. Below is the code snippet: <button mat-raised-button (click)="inputFile.click()">Choose a file</button> <input #inputFile type="file" [style.display]="' ...

Creative Solution for Nested Forms

I am currently facing a challenge with nested forms in my PHP project. I need to include a form for AJAX image upload within another form so that I can pass the file path to the main form. The example code snippet is provided below; <form> <f ...

alert message specific to a certain page (triggered by clicking the back button, accessing the menu, or pressing a particular button

I am facing a dilemma with a web application that allows the administrator (my client) to edit orders. They have expressed a need for warnings to prevent the loss of work. These warnings should trigger if you click on: Buttons such as Save, Work Order, D ...

Unable to fetch data using getJSON method

objecten.js var objectData = [ { image: 'gallery/objecten/bear.jpg', thumb: 'gallery/objecten/bear.jpg', title: 'my first image', description: 'Lorem ipsum caption&apos ...

Issues encountered when incorporating personalized CSS into a Vuetify element

Working with the Vuetify selector input component, v-select, and wanting to customize its style led me to inspecting it in Chrome and copying down the necessary classes. For instance, to change the font size of the active value, I utilized: .v-select__sel ...

Error: Unable to locate the include file

Hello, I am currently a student working on a project where I am attempting to retrieve a list of books from the server and display them one by one using ejs. Here is an overview of my project structure: | |-----routes | |-----index.js |-----vie ...

Unable to access property value in React component

Hello everyone! This is my first time posting here, so I hope I'm explaining this correctly. I've been working on a React multi-step form, and I'm trying to figure out how to display a dynamic number of input fields in one of the steps. The ...

Trigger the Input event on Android with Nuxt

A unique issue has arisen with an input field that filters a list whenever a key is pressed, displaying the filtered results in the browser. While the functionality works perfectly on desktop, it behaves strangely on Android mobiles. The list only shows up ...

Changing the color of specific sprites in three.js

I'm currently exploring three.js and encountering some difficulties when attempting to adjust the color of individual sprites in an array. My reference point is the example provided on this link from threejs.org. The specific task I am working on in ...

A step-by-step guide to extracting live data using cheerio and socketio

I am currently scraping data from a website using Cheerio. Can someone provide me with guidance on how to retrieve web data and automatically update it using socket communication when there are changes on the website? I want to make this process real-tim ...

There was a SyntaxError that caught me by surprise in my Javascript code when it unexpectedly encountered

I have been encountering an error in my code consistently, and I am struggling to comprehend why this is happening. The problematic area seems to be in line 29 of my Javascript file. HTML <link href="Styles12.css"; type="text/css" rel="stylesheet"> ...

What is the importance of utilizing mutation in Vuex to modify the state in a Vue.js application?

I am curious about what might occur if I were to modify the state from a different location, such as directly from the component or through a getter function. Can you provide some insights on this? ...

Bring in multiple classes from node_modules

During the development of my package, I have organized my repository with the following structure: src - Requests.js - Constants.js package.json The package.json file contains the following information: { "name": "package-name", "version": " ...

Creating webpages dynamically by utilizing Javascript

I need assistance with a task involving a list of elements that allows users to print only the clicked element, rather than the entire page. The elements are structured as follows: <div class="element" id="#element1">Element 1</div> <div cl ...

Exploring the utilization of functions beyond module exports

Striving to clearly communicate my intentions, please feel free to ask if anything is unclear. Within a file named www, I am configuring my socket as follows: var server = http.createServer(app); var io = require('socket.io')(server); require(& ...

What is the process for incorporating multiple HTML pages into an Ionic hybrid mobile application?

Struggling to combine my sign in and sign up pages into a single index.html page. I'm currently working on a project involving Hybrid mobile app development. ...

Generating numerous checkboxes dynamically

Seeking assistance with a jQuery function that dynamically generates or clones checkboxes. The challenge is to display the sub_item checkbox when the main_item checkbox is checked. For a demonstration, you can visit this DEMO Jquery $('#btnAdd' ...

"Enhancing Real-Time Communication in Angular with Websockets and $rootScope's Apply

Currently, I am experimenting with an Angular application that utilizes a websocket to interact with the backend. I've encountered some challenges in getting Angular's data binding to function correctly. In this scenario, I have developed a serv ...

Utilize an Express.js controller to retrieve information from an API service and display it on the view

I need assistance with connecting an ExpressJS web app to an API system that responds only with JSON objects. The API system example is: http://example.com/user/13 response: {name:'Aesome 1', age: '13'} The ExpressJS web app cre ...