blessed icon indicating copy to clipboard operation
blessed copied to clipboard

How To Render ASCII Image into Box Content

Open FullstackJack opened this issue 5 years ago • 3 comments

I would like to render an image into the top of a scrollable box so I can scroll the image and description up and down.

I tried appending the image to the box, but it just overlays the text and doesn't scroll the content. I also tried converting the image buffer to string and inserting that as content but maybe I did it wrong, the buffer was a PNG and not an ascii art.

const myContent = 'Lorem Ipsum...';
jimp.read(__dirname + '/john.jpeg', function(err, image) {
        image
          .scaleToFit(80, 80)
          .write(__dirname + '/john.png', (err, image) => {
            image.getBuffer(jimp.MIME_PNG, function (err, image) {
              const box = blessed.box({
                parent: screen,
                padding: 2,
                content: myContent,
                scrollable: true,
                left: 'center',
                top: 'center',
                width: '100%',
                height: '100%',
                style: {
                  bg: 'black',
                  fg: 'green',
                },
                border: 'line',
                keys: true,
                vi: true,
                alwaysScroll: true,
                scrollbar: {
                  ch: ' ',
                  inverse: true
                }
              });


            // Set active
            layout.append(box);
            box.focus();

            // Add image to box...
            png = blessed.image({
              parent: box,
              top: 0,
              scale: 0.1,
              left: 0,
              width: '50%',
              height: Number.parseInt(80 * 9 /16 / 2),
              file: __dirname + '/john.png',
              search: false,
            });
            screen.render();
            screen.on('resize', () => {
              png.clearImage();
              png.setImage(__dirname + '/john.png');
              screen.render();
            })
          });
        });

FullstackJack avatar Sep 12 '18 23:09 FullstackJack

I have an idea. Image has a cellmap property. Should I just convert that multi-dimensional array into a string with newlines at end of each row? What is being stored in each cell of the cell map? An ASCII value?

FullstackJack avatar Sep 12 '18 23:09 FullstackJack

Based on the vendor code that creates the cellmap, it looks like I should be able to do png.img.renderANSI(png.cellmap) to get a string of text that represents the image, but I'm not near a computer to try yet. If that works, I'll resolve this issue.

FullstackJack avatar Sep 13 '18 00:09 FullstackJack

Wow, yeah. Now my code is even uglier, but it's on the right track... I'll have to spend time cleaning this up.

...
// Add image to box...
            const imageContainer = blessed.box({
              parent: screen,
              left: 'center',
              top: 'center',
              width: '100%',
              height: '100%',
              content: '',
            });
            imageContainer.hide();
            png = blessed.image({
              parent: imageContainer,
              top: 0,
              scale: 0.1,
              left: 0,
              width: '100%',
              height: Number.parseInt(80 * 9 /16 / 2),
              file: __dirname + '/john.png',
              search: false,
            });

            screen.render();
            screen.on('resize', () => {
              png.clearImage();
              png.setImage(__dirname + '/john.png');
              const img = png.img.renderANSI(png.cellmap);
              box.setContent(`${img}\n${myContent}`)
              screen.render();
            })
          });
...

FullstackJack avatar Sep 13 '18 00:09 FullstackJack