Coder Social home page Coder Social logo

node-pureimage's Introduction

PureImage

PureImage is a pure 100% JavaScript implementation of the HTML Canvas 2D drawing API for NodeJS. It has no native dependencies. You can use it to resize images, draw text, render badges, convert to grayscale, or anything else you could do with the standard Canvas 2D API. It also has additional APIs to save an image as PNG and JPEG.

Typescript Rewrite

As of version 0.4.* PureImage has been rewritten in 100% Typescript. The module is compiled to both Common JS and ES Modules. If it was working for you before it should still work, but if you notice anything off please file a bug report.

Also note that font.load() now returns a promise instead of using a callback. If you need synchronous support you can still fuse font.loadSync().

Installation

npm install pureimage

Simple example

Make a 100x100 image, fill with red, write to png file

import * as PImage from "pureimage";
import * as fs from "fs";

// make image
const img1 = PImage.make(100, 100);

// get canvas context
const ctx = img1.getContext("2d");

// fill with red
ctx.fillStyle = "red";
ctx.fillRect(0, 0, 100, 100);

//write to 'out.png'
PImage.encodePNGToStream(img1, fs.createWriteStream("out.png"))
  .then(() => {
    console.log("wrote out the png file to out.png");
  })
  .catch((e) => {
    console.log("there was an error writing");
  });

result

red square

supported Canvas Features

note: PureImage values portability and simplicity of implementation over speed. If you need maximum performance you should use a different library backed by native code, such as Node-Canvas

  • set pixels
  • stroke and fill paths (rectangles, lines, quadratic curves, bezier curves, arcs/circles)
  • copy and scale images (nearest neighbor)
  • import and export JPG and PNG from streams using promises
  • render basic text (no bold or italics yet)
  • anti-aliased strokes and fills
  • transforms
  • standard globalAlpha and rgba() alpha compositing
  • clip shapes

On the roadmap, but still missing

  • gradients fills
  • image fills
  • blend modes besides SRC OVER
  • smooth clip shapes
  • bold/italic fonts
  • smooth image interpolation

Why?

There are more than enough drawing APIs out there. Why do we need another? My personal hatred of C/C++ compilers is widely known. The popular Node module Canvas.js does a great job, but it's backed by Cairo, a C/C++ layer. I hate having native dependencies in Node modules. They often don't compile, or break after a system update. They often don't support non-X86 architectures (like the Raspberry Pi). You have to have a compiler already installed to use them, along with any other native dependencies pre-installed (like Cairo).

So, I made PureImage. Its goal is to implement the HTML Canvas spec in a headless Node buffer. No browser or window required.

PureImage is meant to be a small and maintainable Canvas library. It is not meant to be fast. If there are two choices of algorithm we will take the one with the simplest implementation, and preferably the fewest lines. We avoid special cases and optimizations to keep the code simple and maintainable. It should run everywhere and be always produce the same output. But it will not be fast. If you need speed go use something else.

PureImage uses only pure JS dependencies. OpenType for font parsing, PngJS for PNG import/export, and jpeg-js for JPG import/export.

Examples

Make a new empty image, 100px by 50px. Automatically filled with 100% opaque black.

var PImage = require("pureimage");
var img1 = PImage.make(100, 50);

Fill with a red rectangle with 50% opacity

var ctx = img1.getContext("2d");
ctx.fillStyle = "rgba(255,0,0, 0.5)";
ctx.fillRect(0, 0, 100, 100);

Fill a green circle with a radius of 40 pixels in the middle of a 100px square black image.

var img = PImage.make(100, 100);
var ctx = img.getContext("2d");
ctx.fillStyle = "#00ff00";
ctx.beginPath();
ctx.arc(50, 50, 40, 0, Math.PI * 2, true); // Outer circle
ctx.closePath();
ctx.fill();

image of arcto with some fringing bugs

Draw the string 'ABC' in white in the font 'Source Sans Pro', loaded from disk, at a size of 48 points.

test("font test", (t) => {
  var fnt = PImage.registerFont(
    "test/fonts/SourceSansPro-Regular.ttf",
    "Source Sans Pro",
  );
  fnt.loadSync();
  var img = PImage.make(200, 200);
  var ctx = img.getContext("2d");
  ctx.fillStyle = "#ffffff";
  ctx.font = "48pt 'Source Sans Pro'";
  ctx.fillText("ABC", 80, 80);
});

Write out to a PNG file

PImage.encodePNGToStream(img1, fs.createWriteStream("out.png"))
  .then(() => {
    console.log("wrote out the png file to out.png");
  })
  .catch((e) => {
    console.log("there was an error writing");
  });

Read a jpeg, resize it, then save it out

PImage.decodeJPEGFromStream(fs.createReadStream("test/images/bird.jpg")).then(
  (img) => {
    console.log("size is", img.width, img.height);
    var img2 = PImage.make(50, 50);
    var c = img2.getContext("2d");
    c.drawImage(
      img,
      0,
      0,
      img.width,
      img.height, // source dimensions
      0,
      0,
      50,
      50, // destination dimensions
    );
    var pth = path.join(BUILD_DIR, "resized_bird.jpg");
    PImage.encodeJPEGToStream(img2, fs.createWriteStream(pth), 50).then(() => {
      console.log("done writing");
    });
  },
);

This examples streams an image from a URL to a memory buffer, draws the current date in big black letters, and writes the final image to disk

import * as PImage from "pureimage";
import fs from "fs";
import * as client from "https";
let url =
  "https://vr.josh.earth/webxr-experiments/physics/jinglesmash.thumbnail.png";
let filepath = "output_stream_sync.png";
//register font
const font = PImage.registerFont(
  "../test/unit/fixtures/fonts/SourceSansPro-Regular.ttf",
  "MyFont",
);
//load font
font.loadSync();
//get image
client.get(url, (image_stream) => {
  //decode image
  PImage.decodePNGFromStream(image_stream).then((img) => {
    //get context
    const ctx = img.getContext("2d");
    ctx.fillStyle = "#000000";
    ctx.font = "60pt MyFont";
    ctx.fillText(new Date().toDateString(), 50, 80);
    PImage.encodePNGToStream(img, fs.createWriteStream(filepath)).then(() => {
      console.log("done writing to ", filepath);
    });
  });
});

produces

stream example

The same as above but with Promises

import * as PImage from "pureimage";
import fs from "fs";
import * as client from "https";

let url =
  "https://vr.josh.earth/webxr-experiments/physics/jinglesmash.thumbnail.png";
let filepath = "output.png";
let fontpath = "test/unit/fixtures/fonts/SourceSansPro-Regular.ttf";
PImage.registerFont(fontpath, "MyFont")
  .loadPromise()
  //Promise hack because https module doesn't support promises natively)
  .then(() => new Promise((res) => client.get(url, res)))
  .then((stream) => PImage.decodePNGFromStream(stream))
  .then((img) => {
    //get context
    const ctx = img.getContext("2d");
    ctx.fillStyle = "#000000";
    ctx.font = "60pt MyFont";
    ctx.fillText(new Date().toDateString(), 50, 80);
    return PImage.encodePNGToStream(img, fs.createWriteStream(filepath));
  })
  .then(() => {
    console.log("done writing", filepath);
  });

The same as above but with async await

import fs from "fs";
import * as https from "https";
const https_get_P = (url) => new Promise((res) => https.get(url, res));

async function doit() {
  let url =
    "https://vr.josh.earth/webxr-experiments/physics/jinglesmash.thumbnail.png";
  let filepath = "output_stream_async.png";
  //register font
  const font = PImage.registerFont(
    "../test/unit/fixtures/fonts/SourceSansPro-Regular.ttf",
    "MyFont",
  );
  //load font
  await font.load();
  //get image
  let image_stream = await https_get_P(url);
  //decode image
  let img = await PImage.decodePNGFromStream(image_stream);
  //get context
  const ctx = img.getContext("2d");
  ctx.fillStyle = "#000000";
  ctx.font = "60pt MyFont";
  ctx.fillText(new Date().toDateString(), 50, 80);
  await PImage.encodePNGToStream(img, fs.createWriteStream(filepath));
  console.log("done writing to ", filepath);
}
doit()
  .then(() => console.log("done"))
  .catch((e) => console.error(e));

Save a canvas to a NodeJS buffer as PNG using a PassThrough stream:

import * as PImage from "pureimage";
import { PassThrough } from "stream";
const passThroughStream = new PassThrough();
const pngData = [];
passThroughStream.on("data", (chunk) => pngData.push(chunk));
passThroughStream.on("end", () => {});
pureimage.encodePNGToStream(canvas, passThroughStream).then(() => {
  let buf = Buffer.concat(pngData);
  expect(buf[0]).to.eq(0x89);
  expect(buf[1]).to.eq(0x50);
  expect(buf[2]).to.eq(0x4e);
  expect(buf[3]).to.eq(0x47);
  done();
});

Troubleshooting

missing or broken text

PureImage uses OpenType.js to parse fonts and rasterize glyphs. If you are having trouble rendering something first check on the OpenType website that the font can actually be parsed and rendered. If you are rendering non-latin character sets you may need to install an additional dependency to your operating system. For example, rendering arabic text may require pip install arabic-reshaper on Linux.

Using a really large image buffer

PureImage has no inherit size limitations, but NodeJS does have a default max memory setting. You can learn how to increase the default here

New 0.4.x release

After another long lull, I've ported PureImage to Typescript. Most of the work was actually done by the amazing and talented Josh Hemphill. As part of this port I switched to using esbuild for compiling & packaging the Typescript, and Vitest for unit tests. They are vastly faster than our old system.

This release also fixes tons of bugs and adds some small features:

  • updated PngJS, OpenType.jS and JPegJS to their latest version.
  • Node 14 is now the minimum supported version
  • linear and radial gradient fills are supported. See test/gradientfill.test.ts)

New 0.3.x release

After a long lull, I've ported the code to modern ES6 modules, so you can just do an import pureimage from 'pureimage' like any other proper modern module. If you are using require('pureimage') it should just work thanks to the dist/pureimage-umd.cjs file built with Rollup. It also has a stub to let pureimage run in the browser and delegate to the real HTML canvas. This helps with isomorphic apps.

Other updates include

  • Switch to MochaJS for the unit tests.
  • add more unit tests.
  • support drawing images when using transforms
  • implement rect()
  • implement ImageData with getImageData() and putImageData()
  • fix gradient fill
  • add all CSS named colors
  • support #rgb, #rgba, and #rrggbbaa color strings
  • applied more bug fixes from PRs, thanks to our contributors.

New 0.1.x release

I've completely refactored the code so that it should be easier to maintain and implement new features. For the most part there are no API changes (since the API is defined by the HTML Canvas spec), but if you were using the font or image loading extensions you will need to use the new function names and switch to promises. For more information, please see the API docs

I'm also using Node buffers instead of arrays internally, so you can work with large images faster than before. Rich text is no longer supported, which is fine because it never really worked anyway. We'll have to find a different way to do it.

I've tried to maintain all of the patches that have been sent in, but if you contributed a patch please check that it still works. Thank you all! - josh

Thanks!

Thanks to Nodebox / EMRG for opentype.js

Thanks to Rosetta Code for Bresenham's in JS

Thanks to Kuba Niegowski for PngJS

Thanks to Eugene Ware for jpeg-js

Thanks for patches from:

node-pureimage's People

Contributors

adedomin avatar aldy120 avatar bigbizze avatar bilibiliou avatar capse avatar chianquan avatar danielbarela avatar dependabot[bot] avatar fmsy avatar jarrodwatts avatar jeanjpnm avatar joshmarinacci avatar knolleary avatar lightsofapollo avatar lmagder avatar louietan avatar m15h avatar nducrey avatar oligamiq avatar piercus avatar pomax avatar robertmain avatar rse avatar stolex avatar voxpelli avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-pureimage's Issues

context.drawImage

Hi, any ideas why .addImage wouldn't work on a context?

PImage.decodeJPEGFromStream(fs.createReadStream(filePath)).then((img) => {
  var ctx = img.getContext('2d');
  ctx.fillStyle = "red";
  ctx.fillRect(0, 0, img.width, img.height);

  var maskCanvas = PImage.make(img.width, img.height);
  var maskCtx = maskCanvas.getContext('2d');

  maskCtx.fillStyle = "black";
  maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
  ctx.drawImage(maskCanvas, 0,0);
  

  PImage.encodeJPEGToStream(img, fs.createWriteStream(saveOut)).then(()=> {
    console.log("wrote out the png file to out.png");
  }).catch((e)=>{
    console.log("there was an error writing");
  });
});

Here is a sample where the image should come up black but the drawImage call doesn't seem to be effective. This should work with any image load, basically just trying to get a working test case before moving on.

incorrect return type for registerFont

Expected Behaviour

JSDoc comment asserts a return type that isn't void

Actual Behaviour

JSDoc comment claims return type is void

Steps To Reproduce

Using TypeScript:

import * as PImage from "pureimage";
PImage.registerFont("./Font.ttf", "Font", 400, "normal", "normal").load(() => {})

registerFont returns the font object which has a load method, so that should pass typescript checker. However, tsc looks at the JSDoc and believes it returns void

Documentation

Just a note to say that it would be nice to have access to API documentation on how to use things that aren't covered in the README like low-level API methods etc.

I'm happy to help out with this in setting up jsdoc and some kind of build system for you, but I don't know exactly how everything is meant to work so I'd need some help :)

ctx.fillText fails with TypeError: Cannot read property 'getPath' of null

My example code:

  const fnt = PImage.registerFont(__dirname + '/../../resources/Roboto-Light.ttf','Source Sans Pro');
  fnt.load(() => {
    console.log('fnt',fnt);

      ctx.font = "32pt 'Source Sans Pro'";
      ctx.fillText('foo', 550, 555);

fails with

TypeError: Cannot read property 'getPath' of null
    at Object.exports.processTextPath (/project/node_modules/pureimage/src/text.js:62:30)
    at Context.fillText (/project/node_modules/pureimage/src/context.js:411:33)
    at fnt.load (/project/lib/visualise/render.js:58:11)
    at /project/node_modules/pureimage/src/text.js:28:23
    at /project/node_modules/opentype.js/src/opentype.js:220:16
    at /project/node_modules/opentype.js/src/opentype.js:52:9
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:511:3)

TextAlign not setting

I'd like to be able to center the text in the image, however, the ctx.textAlign="center" seems to be ignored.

Image renders, everything seems as it should be, the only issue is with the alignment.

Ideas?

Send images on the fly

First of all awesome work on the 100% PURE image processing library. Hats off to that. I have a usecase where I need to generate images containing text and they cant be stored as there are gonna be 100/1000s of them. Is there a way I can generate an image and send it to the client as a url that the client can view. Basically talking about creating an image on the fly

EDIT 1
It seems a base 64 url would do the job. Can I convert a generated image to a base 64 url

Thank you for your help in advance

Drawing doesn't work correctly

I am trying to draw a pixel on my 100x100 image, but it comes out as a really big box, and the position isn't even correct. Here is all the code i used for drawing it (import, draw, and export):

var canvas;
pimg.decodePNG(fs.createReadStream('canvas.png'),cb=>{
	canvas = cb;
});

var c = canvas.getContext('2d');

c.fillStyle = 'rgba(0,100,100,1)';
c.fillRect(4,4,1,1);

pimg.encodePNG(canvas, fs.createWriteStream('canvas.png'),err=>{
	console.log(err)
});

my result: image

transform clash

Expected Behaviour

Call context.transform() changes the transform.

Actual Behaviour

Error: context.transform is not a function

Steps To Reproduce

The following simple snippet does not work.

require('pureimage').make(2, 2).getContext("2d").transform(1, 1, 0, 0, 1, 1);

Any Relevant Code Snippets

Platform

OS: MacOS
Node Version:
NPM Version:
PureImage Version:

Any Additional Info

It seems the transform key is some kind of object. There is a transform.setTransform that does the same things as transform in the browser. Perhaps this object can be renamed to _transform, and then we just assign this.transform = this._transform.setTransform.

Please bump up the package version for npm

Expected Behaviour

  1. npm install grabs the latest packages

Actual Behaviour

  1. npm install grabs [email protected]

Steps To Reproduce

  1. npm install

Platform

**OS: macOS **
**Node Version: 7.7.3 **
**NPM Version: 4.1.2 **
**PureImage Version: 0.1.3 **

Any Additional Info

npm needs another version bump

uint32

Just noticed that there is a copy of https://github.com/fxa/uint32.js in the pureimage. Would it not be better to pull this in via npm instead? That way, it's less code to be maintained by the repo maintainers...

Unit Tests

Can I look at straightening the tests out? I've already started to put something together locally - but (with your approval) I'll continue and start putting a branch (and ultimately) a PR together? :)

Running in the browser

I'd really like to be able to run this in a web worker thread, operating on an ImageData.data, a Uint8ClampedArray. Is that possible?

I'd love to fork this and try to adapt it for the browser, but I'm not exactly sure if it's possible, or where to start.

Console.log pollution with fonts.

The new version of the library is polluting the console with additional font information.

Example:

PureImage loading Open Sans undefined undefined undefined
searching for font Open Sans
font not found: Open Sans
instead trying family Open Sans

Exported PNG not transparent

Expected Behaviour

  1. Canvas should by default be transparent and so should in my opinion be the exported bitmap if the export format supports that.

Actual Behaviour

var fs = require('fs');
var PImage = require('pureimage');
var img1 = PImage.make(100,50);
PImage.encodePNGToStream(img1, fs.createWriteStream('out.png')).then(()=> {
    console.log("wrote out the png file to out.png");
}).catch((e)=>{
    console.log("there was an error writing");
});

Results an opaque black PNG.

fillRect does not process RGBA

Hello,

I was trying to fillRect with a rgba fillStyle but my image gets filled with the rgb value without taking transparency into account.

Looking at composite implementation, I am not that surprised :)

composite(i,j,old_pixel, new_pixel) {
  return new_pixel;
}

Seems like that a dependency to color-composite could be used.

Thanks,
Nicolas

Extract complex data types

It might be beneficial to extract more complex data types that get passed around to an external file. The one that comes to mind particularly is the concept of a line object.

The library expects that a line looks like this:

{
    start: {
        x: 42,
        y: 30
    }, 
    end: {
        x: 10, 
        y: 20
    }
}

however, it's very difficult for both library consumers and any linters or parsers to know this.

I don't mind putting in a PR to do this, with your approval...

table for richtext

Hi, can you add a feature for richtext: table (without border).
Thank you

draw text loading ttf font

I am trying text rendering in osx and it does not work for me. It render rect or other things but text does not emerge error to load font but it does not render anything.

Get PNG data as a Buffer

I wanted to get the PNG data as a buffer instead of a stream (because I am returning the data to the Loopback4 framework).

Using the tests for inspiration, I came up with this:

async function encodePNGToBuffer(canvas) {
  return encodeAndStreamIntoBuffer(pureimage.encodePNGToStream, canvas);
}

async function encodeJPEGToBuffer(canvas) {
  return encodeAndStreamIntoBuffer(pureimage.encodeJPEGToStream, canvas);
}

async function encodeAndStreamIntoBuffer(encodeDataToStream, canvas) {
  const PassThrough = require('stream').PassThrough;
  const passThroughStream = new PassThrough();
  const pngData = [];
  passThroughStream.on('data', chunk => pngData.push(chunk));
  passThroughStream.on('end', () => {});
  await encodeDataToStream(canvas, passThroughStream);
  return Buffer.concat(pngData);
}

You are welcome to include these in the library if you like.

I would also be interested to hear if anyone knows a better way.

lineTo does not appear to support rgba

context.lineTo() does not appear to work with rgba properly - the lines are always drawn with 100% opacity (aside from anti-aliasing). Also, the lines are a bit off on the corners - the top corner is expected, but the left, right and bottom corners should look like the expected output image (drawn using Canvas in Safari).

Expected Behaviour

https://codepen.io/anon/pen/xWbBrL
expected

  1. Lines drawn should be at 50% opacity (0.5 alpha)
  2. Corners should be correct

Actual Behaviour

https://gist.github.com/rage8885/7ed14eb38c20f6e1678713296d745d3c
out

  1. Lines drawn are always at 100% opacity
  2. Corners are not drawn correctly

remove console logging

Can you remove the console logging that is in Context.getImageData and Context.putImageData?

Use an external drawing library?

Hi all,

A while back I was looking for a canvas/drawing library that doesn't depend on any native code and that could run in both node & browser (webworker). I came across this project but noticed that was severely lacking in (advanced) drawing functionality. Quite normal given the absolutely monumental task of implementing such a thing.

Anyway, in the meantime I discovered Skia (which is actually the library used by browsers to implement their canvas operations), and ported it to wasm. Including a basic set of working bindings.

Purely as a suggestion, perhaps it would be interesting to implement the canvas operations of this project using the skia wasm port as it would most likely yield far better performance, as well as having near all drawing operations already available to you, while still being 100% js compatible/no native code.

fillRect function will leave a black line at the top of the image

My code is like:

const SIZE = 100;
const BGCOLORS = [...some colors...]
...
const avatar = PImage.make(SIZE, SIZE);
const g2d = avatar.getContext('2d');
g2d.fillStyle = BGCOLORS[_.random(BGCOLORS.length - 1)];
g2d.fillRect(0, 0, SIZE, SIZE);
//g2d.fillRect(-1, -1, SIZE + 1, SIZE + 1); // this will work

measureText is not working

measureText is not working because it searches for a _settings property in ctx which is not there.
Instead it should use _font not _settings.font.

When this is fixed it still does not find the font because the font is saved in the wrong format (see #50 )

Save the font correctly

At the moment the code for setting the font is this:

        Object.defineProperty(this,'font', {
            get: function() {

            },
            set: function(val) {
                val = val.trim();
                var n = val.indexOf(' ');
                var size = parseInt(val.slice(0,n));
                var name = val.slice(n);
                this._font.family = name;
                this._font.size = size;
            }
        });

Instead it should be this to have a clean name of the text and not something like \'OpenSans\' (mind the ' and the space)

        Object.defineProperty(this,'font', {
            get: function() {

            },
            set: function(val) {
                val = val.replace(/\s+/g, '');
                var n = val.indexOf(' ');
                var size = parseInt(val.slice(0,n));
                var name = val.slice(n+1).replace(/'/g, '');
                this._font.family = name;
                this._font.size = size;
            }
        });

This results in a clean font OpenSans

Text rendering is slightly pixelated

Is it expected behavior that text rendering is not super sharp? I've tried creating an image in multiple sizes, with multiple font sizes, and with multiple .ttf files from Google Fonts, and the text always appears to be pixelated.

screen shot 2018-01-30 at 1 22 19 pm

Here is my code:

    var fnt = PImage.registerFont('RammettoOne-Regular.ttf', 'RammettoOne');
    fnt.load(function () {
        var img = PImage.make(1500, 1500);
        var ctx = img.getContext('2d');
        ctx.fillStyle = 'rgba(0,0,255, 1.0)';
        ctx.fillRect(0, 0, 1000, 1000);
        ctx.fillStyle = '#ffffff';
        ctx.font = "50pt 'RammettoOne'";
        ctx.fillText("My Trunkshow", 50, 200);

        PImage.encodePNGToStream(img, fs.createWriteStream('out.png')).then(() => {
            response.sendFile('out.png', { root: __dirname });
        }).catch((e) => {
            response.send('Error');
        });
    });

ES6 Imports

Would it be possible to look at using ES6 imports instead of require? Reason being is that ES6 imports are async so they run in parallel, whereas calls to require run synchronously and are therefore very very slow.

Example help?

I am wanting to use pureimage to be able to open a JPG file and draw a rectangle (like as part of face-detection or similar).

I am using google vision APIs to identify faces, and I get rectangle coordinates. I just need help drawing the rectangle on the image.

Thanks in advance!

Drawing image with transparency pastes over image

I'm working on a discord community project, a game through the discord interface, and I'm using PureImage to generate a dungeon map. It's simple, tile-based, but I want it to look nice.

I have a small outline box in another file, and when I try to decode it and paste it onto the tiles, instead of showing the outline, it pastes the entire image into the context, transparency and all.

Is there a way to get the transparency to not replace what is already on the image? Here's what I have so far:
dungeon

Here's an example of what it should look like:
dungeon

Inconsistent Line fill and stray lines

Expected Behaviour

  1. Draw a rectangle rounded corners by using a path and fill.

Actual Behaviour

  1. Sometimes there are stray lines.

Steps To Reproduce

  1. Use the code below. It's worth noting this happens even if I draw a simple rectangle, but I figured I may as well share my exact issue.

Any Relevant Code Snippets

var img = PImage.make(1200, 628),
      ctx = img.getContext('2d'),
      WIDTH = 1200,
      HEIGHT = 628,

ctx.imageSmoothingEnabled = true;

// clear background
ctx.clearRect(0, 0, WIDTH, HEIGHT);

// background
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, WIDTH, HEIGHT);

// top color box
ctx.fillStyle = '#142C6E';
ctx.fillRect(0, 0, 338, HEIGHT / 2);

// bottom color box
ctx.fillStyle = "FF0000";
ctx.fillRect(0, HEIGHT / 2, 338, HEIGHT / 2);

// white rectangle box
ctx.fillStyle = '#00FF00';
roundRect(ctx, 44, 239, 250, 150, 8);

    function roundRect(ctx, x, y, width, height, radius) {
      if (typeof radius === 'undefined') {
        radius = 5;
      }
      if (typeof radius === 'number') {
        radius = {tl: radius, tr: radius, br: radius, bl: radius};
      } else {
        var defaultRadius = {tl: 0, tr: 0, br: 0, bl: 0};
        for (var side in defaultRadius) {
          radius[side] = radius[side] || defaultRadius[side];
        }
      }
      ctx.beginPath();
      ctx.moveTo(x + radius.tl, y);
      ctx.lineTo(x + width - radius.tr, y);
      ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr);
      ctx.lineTo(x + width, y + height - radius.br);
      ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height);
      ctx.lineTo(x + radius.bl, y + height);
      ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl);
      ctx.lineTo(x, y + radius.tl);
      ctx.quadraticCurveTo(x, y, x + radius.tl, y);
      ctx.lineTo(x + radius.tl, y);
      ctx.closePath();
      ctx.fill_aa();
    }

Platform

OS: OSX
Node Version: 8.8.1
NPM Version: 5.6.0
PureImage Version: 0.1.4 (also, have tried installing from github)

Any Additional Info

See these images:

Working:
working

Broken:
broken

utf8 font support

Expected Behaviour

Unicode and rtl languages support on fillText methof
text like سلام دنیا

Actual Behaviour

all characters shows in reverse direction

سلام دنیا
ا ی ن د م ا ل س

Platform

**OS: debian
**Node Version: v8.1.3
**PureImage Version : 0.1.3

decodePNGFromStream() causes PNGs to lose their transparency.

Using PImage.decodePNGFromStream causes PNG files with transparency to render without any.

Tried new PNG({ colorType: 6, inputHasAlpha: true }) and on the metadata event, everything seems fine.

I guess the bug is somewhere inside the Bitmap class.

Any help would be really appreciated,
Thank you in advance fellow developers :)

Drawing gradients doesn't work

Expected Behaviour

  1. When using createLinearGradient, should work

Actual Behaviour

  1. c.createLinearGradient is not a function

Steps To Reproduce

  1. Copy the code from https://joshmarinacci.github.io/node-pureimage/test-file/specs/gradientfill.test.js.html#lineNumber3
  2. Run

Any Relevant Code Snippets

  var PImage = require('pureimage');
  let image  = PImage.make(20,20)
  let c = image.getContext('2d');
  c.fillStyle = 'black'
  c.fillRect(0,0,200,200)

  const grad = c.createLinearGradient(0,0,20,20)
  grad.addColorStop(0,'white')
  grad.addColorStop(1,'blue')

Platform

OS: Windows 10, Ubuntu 18
Node Version: v10.15.0
NPM Version: 6.13.7
PureImage Version: 0.1.6

Any Additional Info

Its definately in the code base:
https://github.com/joshmarinacci/node-pureimage/blob/1d4bdd54e1e4f1b3ed9f94cb90c639bfbe078cd3/src/context.js

arc() dont work as expected

Expected Behaviour

  1. using canvas.js or in browser: ctx.arc(100,100,50,1.7Math.PI,0.7Math.PI);

canvas

Actual Behaviour

  1. using pureimage: ctx.arc(100,100,50,1.7Math.PI,0.7Math.PI);

pureimage

Steps To Reproduce

Any Relevant Code Snippets

canvas:

{	const { createCanvas } = require('canvas');
	const canvas = createCanvas(200, 200);
	const ctx = canvas.getContext('2d');
	ctx.beginPath();
	ctx.fillStyle = "white";
	ctx.fillRect(0, 0, 200, 200);
	ctx.beginPath();
	ctx.arc(100,100,50,1.7*Math.PI,0.7*Math.PI);
	ctx.stroke();	
	const fs = require('fs');
	const out = fs.createWriteStream('canvas.png');
	const stream = canvas.createPNGStream();
	stream.pipe(out);
}

pureimage

{	var PImage = require('pureimage');
	var img = PImage.make(200, 200);
	var ctx = img.getContext('2d');
	ctx.beginPath();
	ctx.fillStyle = "white";
	ctx.fillRect(0, 0, 200, 200);
	ctx.beginPath();
	ctx.arc(100,100,50,1.7*Math.PI,0.7*Math.PI);
	ctx.stroke();	
	var fs = require('fs');
	PImage.encodePNGToStream(img, fs.createWriteStream('pureimage.png'));
}

Platform

**OS:**ubuntu 16.04
**Node Version:**v8.15.1
**NPM Version:**6.4.1
**PureImage Version:**[email protected]

Any Additional Info

setFillStyleRGBA not found

I tried this from the Readme

var img1 = PImage.make(100,50);
var ctx = img1.getContext('2d');
ctx.setFillStyleRGBA(255,0,0, 0.5);

But I get this error TypeError: ctx.setFillStyleRGBA is not a function

I have pureimage v0.0.13 and Nodejs v7.4.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.