Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request: bmp format image support #806

Closed
Nomia opened this issue May 13, 2017 · 10 comments
Closed

feature request: bmp format image support #806

Nomia opened this issue May 13, 2017 · 10 comments
Labels

Comments

@Nomia
Copy link

Nomia commented May 13, 2017

this is a feature request,

would this lovely project support bmp format image manipulation?

@lovell
Copy link
Owner

lovell commented May 13, 2017

Hello, please see #543

@Nomia
Copy link
Author

Nomia commented May 14, 2017

Thanks I used jimp to handle bmp format images.

@Nomia Nomia closed this as completed May 14, 2017
@Nomia
Copy link
Author

Nomia commented May 14, 2017

here is the link: https://github.com/oliver-moran/jimp

read a bmp file, then export it as a jpeg buffer, then send it to sharp

@lovell
Copy link
Owner

lovell commented May 14, 2017

I believe https://github.com/shaozilee/bmp-js is the underlying library used by jimp.

It might be possible to remove the jpeg compression round-trip by using it directly with sharp, something like (untested):

const bmpDecoded = bmp.decode(bmpBuffer);

sharp(bmpDecoded.data, { raw: {
  width: bmpDecoded.width,
  height: bmpDecoded.height,
  channels: 4
}})...

@Nomia
Copy link
Author

Nomia commented May 14, 2017

Great, thanks!

@mooyoul
Copy link

mooyoul commented Sep 8, 2018

Unfortunately, decoded channel order of bmpjs is BGR order, which is not compatible with sharp (sharp uses RGB order - RGBA if 4 channels defined.)

So we've forked bmp-js to provide RGBA option, with improved bitmap format compatibility. (tested with 1/2/4/8/16/24/32bit bitmap image)

Forked repo: https://github.com/balmbees/bmp-js

Just follow below steps to load bitmap images:

  1. install @vingle/bmp-js package
$ npm install @vingle/bmp-js --save
  1. Change your code like this:

Old:

import * as sharp from "sharp";

async function transform(input: Buffer): Promise<Buffer> {
  const sharpInstance = sharp(input);
  
   // do stuff...

  return await sharpInstance.jpeg().toBuffer();
}

New:

import * as bmp from "@vingle/bmp-js";
import * as sharp from "sharp";

const BUF_BMP = Buffer.from([0x42, 0x4d]); // "BM" file signature

function isBitmap(buf: Buffer): boolean {
  return Buffer.compare(BUF_BMP, buf.slice(0, 2)) === 0;
}

async function transform(input: Buffer): Promise<Buffer> {
  const sharpInstance = (() => {
    if (isBitmap(buf)) {
      const bitmap = bmp.decode(buf, true);
      return sharp(bitmap.data, {
        raw: {
          width: bitmap.width,
          height: bitmap.height,
          channels: 4,
        },
      });
    }
    return sharp(buf);
  })();
  
  // do stuff..

  return await sharpInstance.jpeg().toBuffer();
}

Hope this helps!

@ssnangua
Copy link

ssnangua commented Aug 4, 2022

I added an adapter to bmp-js for sharp, it's easy to use.

See: https://github.com/ssnangua/sharp-bmp

  1. Install sharp-bmp package
npm install sharp-bmp
  1. Create an instance of sharp from a BMP image
const bmp = require("sharp-bmp");

bmp.sharpFromBmp("input.bmp", {
  // sharp constructor options
}) // returns an instance of sharp
  .toFile("output.png");
  1. Write output image data to a BMP file
const sharp = require("sharp");
const bmp = require("sharp-bmp");

const image = sharp("input.jpg");

bmp.sharpToBmp(image, "output.bmp")
  .then((info) => {
    console.log(info); // { size, width, height }
  })
  .catch((err) => {
    console.error(err);
  });

Hope this helps :-)

@rnavarroz
Copy link

I used https://github.com/mooyoul/bmp-js already has the option to convert the BRG to RGBA
npm install @vingle/bmp-js
and use it:

const fs = require('node:fs');
const fsp = fs.promises;
const bmp = require('@vingle/bmp-js');
const sharp = require('sharp');

const buffer = await fsp.readFile('input.bmp');
const bitmap = bmp.decode(buffer, true); // boolean flag to convert to RGBA

const image = sharp(bitmap.data, { raw: {
  width: bitmap.width,
  height: bitmap.height,
  channels: 4
}})

see more in shaozilee/bmp-js#19

@Jeff-Tian
Copy link

shaozilee/bmp-js#19

Hi @mooyoul, thanks for your code snippet! Can you also share another version that accepts stream instead of buffer?

Is it possible that the method accepts a stream, and detects if it's BMP type? If so, then use BMP-js to decode and pipe to another stream. If not then pipe to the other stream directly without using bmp-js?

Thanks for your sharing!

@sineastra
Copy link

I added an adapter to bmp-js for sharp, it's easy to use.

See: https://github.com/ssnangua/sharp-bmp

  1. Install sharp-bmp package
npm install sharp-bmp
  1. Create an instance of sharp from a BMP image
const bmp = require("sharp-bmp");

bmp.sharpFromBmp("input.bmp", {
  // sharp constructor options
}) // returns an instance of sharp
  .toFile("output.png");
  1. Write output image data to a BMP file
const sharp = require("sharp");
const bmp = require("sharp-bmp");

const image = sharp("input.jpg");

bmp.sharpToBmp(image, "output.bmp")
  .then((info) => {
    console.log(info); // { size, width, height }
  })
  .catch((err) => {
    console.error(err);
  });

Hope this helps :-)

Great work man.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants