GithubHelp home page GithubHelp logo

nodeca / pica Goto Github PK

View Code? Open in Web Editor NEW
3.7K 53.0 241.0 21.91 MB

Resize image in browser with high quality and high speed

Home Page: http://nodeca.github.io/pica/demo/

License: MIT License

JavaScript 83.61% HTML 0.59% C 15.35% Shell 0.45%
image resize

pica's Introduction

pica - high quality image resize in browser

CI NPM version

Resize images in browser without pixelation and reasonably fast. Autoselect the best of available technologies: webworkers, webassembly, createImageBitmap, pure JS.

demo

With pica you can:

  • Reduce upload size for large images, saving upload time.
  • Saves server resources on image processing.
  • Generate thumbnails in browser.
  • ...

Note. If you need File/Blob resize (from form's file input), consider use image-blob-reduce. It has additional machinery to process orientation, keep EXIF metadata and so on.

Migration from pica v6 to pica v7

Multiply unsharpAmount by 2, divide unsharpThreshold by 2, example:

  • pica@6: pica.resize(a, b, { unsharpAmount: 80, unsharpThreshold: 2 })
  • pica@7: pica.resize(a, b, { unsharpAmount: 160, unsharpThreshold: 1 })

Prior to use

Here is a short list of problems you can face:

  • Loading image:
    • Due to JS security restrictions, you can process images from the same domain or local files only. If you load images from remote domain use proper Access-Control-Allow-Origin header.
    • iOS has a memory limits for canvas elements, that may cause problems in some cases, more details.
    • If your source data is jpeg image, it can be rotated. Consider use image-blob-reduce.
  • Saving image:
    • Some ancient browsers do not support canvas.toBlob() method. Use pica.toBlob(), it includes required shim.
    • For jpeg source, it's a good idea to keep exif data. Consider use image-blob-reduce.
  • Quality
    • JS canvas does not support access to info about gamma correction. Bitmaps have 8 bits per channel. That causes some quality loss, because with gamma correction precision could be 12 bits per channel.
    • Precision loss will not be noticeable for ordinary images like kittens, selfies and so on. But we don't recommend this library for resizing professional quality images.

Install

npm install pica

Use

const pica = require('pica')();

// Resize from Canvas/Image to another Canvas
pica.resize(from, to)
  .then(result => console.log('resize done!'));

// Resize & convert to blob
pica.resize(from, to)
  .then(result => pica.toBlob(result, 'image/jpeg', 0.90))
  .then(blob => console.log('resized to canvas & created blob!'));

API

new Pica(config)

Create resizer instance with given config (optional):

  • tile - tile width/height. Images are processed by regions, to restrict peak memory use. Default 1024.
  • features - list of features to use. Default is [ 'js', 'wasm', 'ww' ]. Can be [ 'js', 'wasm', 'cib', 'ww' ] or [ 'all' ]. Note, cib is buggy in Chrome and not supports default mks2013 filter.
  • idle - cache timeout, ms. Webworkers create is not fast. This option allow reuse webworkers effectively. Default 2000.
  • concurrency - max webworkers pool size. Default is autodetected CPU count, but not more than 4.
  • createCanvas - function which returns a new canvas, used internally by pica. Default returns a <canvas> element, but this function could return an OffscreenCanvas instead (to run pica in a Service Worker). Function signature: createCanvas(width: number, height: number): Canvas

Important! Latest browsers may support resize via createImageBitmap. This feature is supported (cib) but disabled by default and not recommended for use. So:

  • createImageBitmap() is used for non-blocking image decode (when available, without downscale).
  • It's resize feature is blocked by default pica config. Enable it only on your own risk. Result with enabled cib will depend on your browser. Result without cib will be predictable and good.

.resize(from, to, options) -> Promise

Resize image from one canvas (or image) to another. Sizes are taken from source and destination objects.

  • from - source, can be Canvas, Image or ImageBitmap.
  • to - destination canvas, its size is supposed to be non-zero.
  • options - quality (number) or object:
    • quality (deprecated, use .filter instead) - 0..3.
    • filter - filter name (Default - mks2013). See resize_filter_info.js for details. mks2013 does both resize and sharpening, it's optimal and not recommended to change.
    • unsharpAmount - >=0. Default = 0 (off). Usually value between 100 to 200 is good. Note, mks2013 filter already does optimal sharpening.
    • unsharpRadius - 0.5..2.0. By default it's not set. Radius of Gaussian blur. If it is less than 0.5, Unsharp Mask is off. Big values are clamped to 2.0.
    • unsharpThreshold - 0..255. Default = 0. Threshold for applying unsharp mask.
    • cancelToken - Promise instance. If defined, current operation will be terminated on rejection.

Result is Promise, resolved with to on success.

(!) If you need to process multiple images, do it sequentially to optimize CPU & memory use. Pica already knows how to use multiple cores (if browser allows).

.toBlob(canvas, mimeType [, quality]) -> Promise

Convenience method, similar to canvas.toBlob(), but with promise interface & polyfill for old browsers.

.resizeBuffer(options) -> Promise

Supplementary method, not recommended for direct use. Resize Uint8Array with raw RGBA bitmap (don't confuse with jpeg / png / ... binaries). It does not use tiles & webworkers. Left for special cases when you really need to process raw binary data (for example, if you decode jpeg files "manually").

  • options:
    • src - Uint8Array with source data.
    • width - src image width.
    • height - src image height.
    • toWidth - output width, >=0, in pixels.
    • toHeight - output height, >=0, in pixels.
    • quality (deprecated, use .filter instead) - 0..3.
    • filter - filter name (Default - mks2013). See resize_filter_info.js for details. mks2013 does both resize and sharpening, it's optimal and not recommended to change.
    • unsharpAmount - >=0. Default = 0 (off). Usually value between 100 to 200 is good. Note, mks2013 filter already does optimal sharpening.
    • unsharpRadius - 0.5..2.0. Radius of Gaussian blur. If it is less than 0.5, Unsharp Mask is off. Big values are clamped to 2.0.
    • unsharpThreshold - 0..255. Default = 0. Threshold for applying unsharp mask.
    • dest - Optional. Output buffer to write data, if you don't wish pica to create new one.

Result is Promise, resolved with resized rgba buffer.

What is "quality"

Pica has presets to adjust speed/quality ratio. Simply use quality option param:

  • 0 - Box filter, window 0.5px
  • 1 - Hamming filter, window 1.0px
  • 2 - Lanczos filter, window 2.0px
  • 3 - Lanczos filter, window 3.0px

In real world you will never need to change default (max) quality. All this variations were implemented to better understand resize math :)

Unsharp mask

After scale down image can look a bit blured. It's good idea to sharpen it a bit. Pica has built-in "unsharp mask" filter (off by default). Set unsharpAmount to positive number to activate the filter.

Filter's parameters are similar to ones from Photoshop. We recommend to start with unsharpAmount = 160, unsharpRadius = 0.6 and unsharpThreshold = 1. There is a correspondence between UnsharpMask parameters in popular graphics software.

Browser support

We didn't have time to test all possible combinations, but in general:

Note. Though you can run this package on node.js, browsers are the main target platform. On server side we recommend to use sharp.

References

You can find these links useful:

pica for enterprise

Available as part of the Tidelift Subscription.

The maintainers of pica and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. Learn more.

pica's People

Contributors

a-rodin avatar adrianmg avatar avalanche1 avatar d08ble avatar devongovett avatar doodlewind avatar farseeing avatar fchapoton avatar greghuc avatar ianedington avatar kisvegabor avatar llacroix avatar maxkuzmin avatar rlidwka avatar sandstrom avatar thokari avatar timoxley avatar tombyrer avatar varlog avatar vinnymac avatar yoranbrondsema 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  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

pica's Issues

Creating weird tiling with large file?

When creating a png image, it seems to be creating multiple instances of the original image on the canvas. Maybe I'm doing something wrong.

See the attached image. It is 2048x2048 and then the output is tiled.

function icons(){
    var pica = require('pica');
    var Canvas = require('canvas');
    var Image = Canvas.Image;

    var colors = require(theme + '/lib/colors.js');
    var sizes = [
      /*{ width: 29, height: 29, title: 'appicon-Small.png'},
      { width: 58, height: 58, title: '[email protected]'},
      { width: 40, height: 40, title: 'appicon-Small-40.png'},
      { width: 80, height: 80, title: '[email protected]'},
      { width: 76, height: 76, title: 'appicon-76.png'},
      { width: 152, height: 152, title: '[email protected]'},*/
      { width: 167, height: 167, title: '[email protected]'},
    ]

    fs.readFile(build + '/DefaultIcon.png', function(err, logo){
      if (err) throw err;

      images();

      function images(){
        if(!sizes.length) return console.log('finished');
        var size = sizes.shift();
        var canvas = new Canvas(size.width, size.height);

        var out = fs.createWriteStream(base + '/' + size.title)
        var stream = canvas.pngStream();
        stream.on('data', function(chunk){
          out.write(chunk);
        });
        stream.on('end', function(){
          console.log('end');
          images();
        });

        var ctx = canvas.getContext('2d');
        //var grd=ctx.createLinearGradient(0,0,0,size.height);
        //grd.addColorStop(0, colors.primary);
        //grd.addColorStop(1, colors.secondary);
        ctx.fillStyle=colors.secondary;
        ctx.fillRect(0,0,size.width,size.height);

        var _canvas = new Canvas(size.width - 10, size.height - 10);
        var img = new Image;
        img.dataMode = Image.MODE_MIME | Image.MODE_IMAGE; // Both are tracked
        img.onload = function(){
          pica.resizeCanvas(img, _canvas, {
            alpha: true,
          }, function(err){
            console.log('wrote data');
            if(err) return; // should terminate here
            //ctx.drawImage(_canvas, 5, 5);
            // doing it this way to make sure it's not a stream write problem.
            _canvas.toBuffer(function(err, data){
              fs.writeFileSync(base + '/test.png', data);
            })
          })
        }
        img.src = logo;
      }

    });
  }

screen shot 2016-09-20 at 2 30 56 pm

defaulticon

Suggestion : expose Worker to allow resize operations to be cancelled

First of all. awesome job with Pica....

In our use case there are many user interactions that may cause a currently running resize operation to no longer be required.

For example:

User is navigating through an album of photos, we perform a quick resize via canvas (downstepping by 1/2's) then fire off a call to pica to create a higher quality image, updating once the resize operation is complete. However the user may of course move onto another photo while the resizing is still taking place, causing the currently running operation to be redundant.

Adding the ability to programmatically cancel a running operation should be trivial..

Add unsharp mask

For practical tasks, it's required to combine downscale with unsharp mask.

  1. For convenience, it worth to use the same prams as photoshop USM http://stackoverflow.com/questions/13296645/
  2. More to read http://stackoverflow.com/questions/2938162/
  3. Gimp implementation https://git.gnome.org/browse/gimp/tree/plug-ins/common/unsharp-mask.c
  4. Luminance / brightness math http://stackoverflow.com/questions/596216/
  5. Bugzilla discusion https://bugzilla.mozilla.org/show_bug.cgi?id=867594

Details:

  • It's ok to support only 1px blur radius. That will require minimal convolution matrix 3x3, and will be fast enougth
  • (!) unsharp luminance, not separate channels, to avoid color shift
  • (!) use high precision (> 8 bits) for luminance calculations.

Algorythm:

  1. build array of L (luminance) values (16 or 32 bits). 4x less points for convolution, as bonus.
  2. for each L point, calculate convolution, check threshold and update rgb on original if needed.
  3. additional requirements:
    • use integer math only (int32)
    • don't use division

Blur:

Other:

Nearest neighbor too good?

I was testing pica with quality == 0 against an implementation I made of nearest neighbor interpolation and noticed that the image from pica was much smoother. Analysing pica's code I noticed that filterSize is 8 with quality 0. Shouldn't the filtersize be 1 in this case? Did I misunderstand how this interpolation works?

Resize with image as a source

Thank you for the library!

Just a quick question - the Readme states, that you can "Resize image from one canvas (or image) to another". Is there really a possibility to resize only the image or do we always need to involve the canvas for input?

Currently I got it working like this:

  1. get image from form and convert to blob.
  2. load the blob to a new Image() and when it's loaded put it to canvas.
  3. using resizeCanvas resize the canvas to another canvas with the proper size.

(and don't we loose the quality if we still use the canvas as a source?)

Black background when resizing transparent png

Hi,

We are using pica and it's great!

However, we are experiencing an unwanted behavior when resizing PNG images with transparent backgrounds.

I have attached two images.

You can reproduce on your demo page.

Thanks!

mailsquad

gray-twitter-96

WebGL? Anyone?

Does anyone wish to make WebGL resize implementation? I don't know if WebGL allows to work with images of any size and is it technically possible to solve this task. But convolver should be extremely fast there.

PS. I'm far from this area, and will not find time to dig it.

JPEG output

This is an awesome library ⛵

I wonder if it's possible to generate JPEG output, currently it seems to be only PNG.

Upgrade browserify bundle to latest webworkify to get around an IE Edge web worker issue

Webworkify 1.2.1 has a known issue in IE Edge that prevents web workers from emitting messages (see here: browserify/webworkify#26).

We ran into this issue when using the latest browserified pica.js package, which uses webworkify 1.2.1. The issue has been tackled in a minor version bump on Webworkify (1.3.0) and could be included in Pica by upgrading. I think it might require some changes in Pica too since the library will now need to explicitly revoke the worker URLs to avoid leaking them.

Upcoming pica 2.0 changes

Pica is currently in process of rewrite. Goals are:

  • restrict resource use, to allow more advanced algorythms
    • floating point for intermediate data between horisontal/vertical passes, requires 4x more memory.
    • webgl has restriction for max texture size
  • utilize parallel processing, when possible (web workers).

How will it work:

  • Split image by tiles (512x512...1024x1024), to restrict memory for each step
    • Since result will be inaccurate on edges, each tile will include additional "border" to drop later.
    • according to our experiments, 1024x1024 tile size is optimal for speed. That's 4mb of raw data. If we decide to use floats without interleave, that will require 20mb internal buffers in lanczos filter. Tile size reduce to 512x512 eats 20% of speed.
    • border size:
      • minimal is 3px of destination image * scale (defined by filer window size)
      • maximal depends on required blur radius for unsharp
  • Use worker pool for parallel processing.

API changes:

  • Drop resizeBuffer as useless and breaking data flow. Pica should always use Canvas or Image for input.
    • this method will be available intarnally, but with changed signature. We now have to pass float scale/offset, to properly locate input/output tiles data.
  • Drop WW id exposure, replace with internal ID.
  • Restrict max allowed blur radius to 1.0-2.0 for unsharp, because it increase tile border size.
    • Even if we change algorythm to blur image before resize, it will need 0.2-0.5 blur radius
    • Current required blur radius is < 2.0
  • Proposed API
    • .resize(srcCanvas/srcImage, destCanvas, options, callback) -> taskID
    • .terminate(taskID) - for example, if user leave page via ajax and you wish to quickly free resources
    • .WW, .WEBGL, .concurrency - fine tune params if autodetect is not enougth.

Later

  • Experiment with blur before resize instead of unsharp mask.
    • For small radius direct kernel calculation can be more effective than glur + HSL transforms.
  • Care about GPU sharpener for webgl resizer.
  • Rework webgl resizer to use precalculated filters (as native resizer does).

I cc this issue to all who created important tickets and helped to improve pica. If you have ideas about API improvment - let me know. Also let me know, if you have ideas how to test webgl on multiple mobile devices.

/cc @dene-, @devongovett, @gordyr, @a-rodin, @noomorph.

Pica not posting the image data to the action file (please help)

@scottcheng I'm trying to set data created by pica to a hidden form field and than submit that form to a php file to show that data as an image, when I do it the normal canvas way, it works, but when i try to do it through pica it doesn't work, following is the code for both the cases.

  1. The following code implements it through normal canvas and it works.
<form action="http://localhost/img_upload/image/upload" id="input-form" method="post" accept-charset="utf-8">
    <div class="image-editor">
        <input type="file" class="cropit-image-input">
        <div class="cropit-image-preview"></div>
        <div class="image-size-label">
          Drag Slider to zoom
        </div>
        <input type="range" class="cropit-image-zoom-input">
        <input type="hidden" name="image-data" class="hidden-image-data" />
        <button type="submit">Submit</button>
      </div>
</form>


<script>
  $(function() {
    $('.image-editor').cropit();

    $('#input-form').submit(function() {

      // Move cropped image data to hidden input
      var imageData = $('.image-editor').cropit('export', {type: 'image/jpeg',quality: .75});
      $('.hidden-image-data').val(imageData);

      // don't submit the form if the imageData is empty
      // for example if user is clicking on the submit without loading an image
      if (imageData == null) {
        return false;
      }
    });
  });
</script>
  1. The following code tries to implement it through pica and fails.
<form action="http://localhost/img_upload/image/upload" id="input-form" method="post" accept-charset="utf-8">
    <div class="image-editor">
      <input type="file" class="cropit-image-input">
      <div class="cropit-image-preview"></div>
      <div class="image-size-label">
        Drag slider to zoom
      </div>
      <input type="range" class="cropit-image-zoom-input">
      <input type="hidden" name="image-data" class="hidden-image-data">
      <input type="submit" value="Upload">
    </div>
</form>


<script>
  $(document).ready(function() {
    var $editor = $('.image-editor');
    $editor.cropit();

    $('#input-form').submit(function() {
      // Get cropping information
      var imgSrc = $editor.cropit('imageSrc');
      var offset = $editor.cropit('offset');
      var zoom = $editor.cropit('zoom');
      var previewSize = $editor.cropit('previewSize');
      var exportZoom = $editor.cropit('exportZoom');

      var img = new Image();
      img.src = imgSrc;

      // Draw image in original size on a canvas
      var originalCanvas = document.createElement('canvas');
      originalCanvas.width = previewSize.width / zoom;
      originalCanvas.height = previewSize.height / zoom;
      var ctx = originalCanvas.getContext('2d');
      ctx.drawImage(img, offset.x / zoom, offset.y / zoom);

      // Use pica to resize image and paint on destination canvas
      var zoomedCanvas = document.createElement('canvas');
      zoomedCanvas.width = previewSize.width * exportZoom;
      zoomedCanvas.height = previewSize.height * exportZoom;
      pica.resizeCanvas(originalCanvas, zoomedCanvas, {
        // Pica options, see https://github.com/nodeca/pica


      }, function(err) {
        if (err) { return console.log(err); }

        // Resizing completed
        // Read resized image data
        var picaImageData = zoomedCanvas.toDataURL('image/jpeg', .75);
        $('.hidden-image-data').val(picaImageData);

      });

      if (picaImageData == null) {
        return false;
      }

    });
  });
</script>

The server side code is a CodeIgniter's controller as follow (for both the normal canvas and pica's examples),

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Image extends CI_Controller {

  public function index()
  {
    $this->load->view('upload_form'); // the upload form shown above
  }

  public function upload()
  {
    $image = $this->input->post('image-data');
    echo "<img src='$image'>";
  }

}

I don't know where is the problem in the code. Please help me. Thank You.

Any way to resize images from blob?

Hi, it seems as pica a great library, but it really complex to dive in for newbies like me. What steps I should to do to resize image from a form? I get image as blob and what then? Put this image to a hidden canvas, then resize it with pica to another hidden canvas? Is there some simply way to resize it with pica?

SCRIPT5022: IndexSizeError in IE11 when using webworkers.

I sometimes get an error with IE11, it kind of depends on the image. I try to write a set of 8 images to another canvas. This is done after resizing the images with pica. It works perfectly in chrome and firefox, but for IE11 it only works if i use WebGL.

The error is in resize_js_ww
fromTileCtx.drawImage(from, tile.x, tile.y, tile.width, tile.height, 0, 0, tile.width, tile.height);

I'm having a hard time debugging this. It feel like it is trying to create an image larger than the canvas mabye?

I tried to make a fiddle to show the problem, but i have a hard time isolating the problem.

Webworker in IE11 and Edge does not work and stalls. Possible issue with support for canvas data.

Both browsers in Windows 10 fails to get past

Resize buffer in WebWorker

Unfortunately if I disable web workers like in IE11 on Windows 7 the entire browser freezes until it's finished running the massive loop for the resizing.

window.pica.resizeCanvas(this.srcCanvas, this.dstCanvas, this.picaConfig , this.onBlobResize.bind(this));

My code looks like this. the source canvas is not an image but a html5mediaelement.

If I enable WebGL Edge works fine but if it's disabled and tries to use webworkers it stalls. No callback happens and no log is sent.

If WebGL is enabled IE11 on Windows 10 tries to use that but I get a black canvas so that is broken on IE11 on Windows 10.

Is WebGL stable to use now in terms of the aliasing ? I don't seem to see this aliasing problem at all.

I guess I have to be selective what can use WebGL but I also need to figure out why any of the IE browsers do not like Webworkers either.

Experimental, WebGL resize incorrectly renders alpha channel

Tested experimental feature WebGL driver which incredibly speeds up rendering (!) even with large images, great work!
There is a glitch when using alpha channel png images. When WEBGL is turned off it resizes images beautifully:
correct
After turning WEBGL:
incorrect

I've tested this on latest versions of Chrome, Safari, Opera and Firefox on Mac OS X 10.11. Please let me know whether you need any additional information.

The new feature kicks-ass, please improve! :)

Understanding Unsharp algorithm

Hi,
just looking into your unsharp algorithm and I got lost in last step. Could you explain me one thing.
I assume that you implement this formula USM(O) = O + (2 * (Amount / 100) * (O - GB)), right?

What puzzle me is that you are using multiplication (c * corr) for the correction and not addition as the formula above suggests. Is that intention? Maybe its some optimization that I don't understand :-).

Thank you for hint!

Animated GIFs

Hi,

I've been trying to find a javascript library capable of resize an animated gif in the browser and preserve the animation. Pica does not seem to have the preserve animation ability.

Wondering, is it something doable?

If so, Could you guys show me how I can contribute to pica and implement that feature?

Thanks!

Use createImageBitmap if available

https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmapFactories/createImageBitmap

I was hoping pica would solve my performance issues, but it does not. Resizing in a web worker is great, but the problem is decoding the image data on the UI thread. My test image is 7200x4800 and 4.5 MB (https://hd.unsplash.com/photo-1414396938948-81a7045e336f).

The UI is blocked for about 700ms due to "Image Decode" triggered by getImageData.

screenshot from 2016-10-19 12 23 16

Do you think we can use a File/Blob object, pass it to the web worker and decode the image there?

Note: you can not see this on the demo page, because you are rendering the images and the timeline doesn't show "Image Decode" separately but as part of "Composite Layers". If you hide the elements in the demo (display: none) you can see it. For the demo it's unavoidable to have image decoding on the UI thread, as you display the original image. But in the real world you might use pica to resize the image and then upload it, while never displaying the original to the user.

screenshot from 2016-10-19 12 27 04
screenshot from 2016-10-19 12 27 30

Possible brighness change on resize

After #20

I don't know is it correct or not, but should resize keep brightness "energy" intact? Simple check - resize white box. Should resize be exactly white (FFFFFF) or can be FEFEFE?

Need to recheck filter weights and rounding 14 bit <-> 8 bit everywhere.

With Webpack I face below error while using pica

I am trying to use pica with react app created using create react app module
Anyway to fix this?

Uncaught TypeError: __webpack_require__(...).readFileSync is not a function at Object.<anonymous> (resize_webgl.js:14) at Object.<anonymous> (resize_webgl.js:385) at __webpack_require__ (bootstrap bb72531…:555) at fn (bootstrap bb72531…:86) at Object.<anonymous> (index.js:39) at __webpack_require__ (bootstrap bb72531…:555) at fn (bootstrap bb72531…:86) at Object.<anonymous> (App.js:6) at __webpack_require__ (bootstrap bb72531…:555) at fn (bootstrap bb72531…:86)

Question: how to use pica with webpack?

If we do require('pica') and we compile our app with webpack (target: 'web') then build fails with:

ERROR in ./~/pica/lib/resize_webgl.js
Module not found: Error: Cannot resolve module 'fs' in /home/user/myapp/node_modules/pica/lib
resolve module fs in /home/user/myapp/node_modules/pica/lib
  looking for modules in /home/user/myapp/node_modules
    /home/user/myapp/node_modules/fs doesn't exist (module as directory)
    resolve 'file' fs in /home/user/myapp/node_modules
      resolve file
        /home/user/myapp/node_modules/fs doesn't exist
        /home/user/myapp/node_modules/fs.webpack.js doesn't exist
        /home/user/myapp/node_modules/fs.web.js doesn't exist
        /home/user/myapp/node_modules/fs.js doesn't exist
        /home/user/myapp/node_modules/fs.json doesn't exist
[/home/user/myapp/node_modules/fs]
[/home/user/myapp/node_modules/fs]
[/home/user/myapp/node_modules/fs.webpack.js]
[/home/user/myapp/node_modules/fs.web.js]
[/home/user/myapp/node_modules/fs.js]
[/home/user/myapp/node_modules/fs.json]
 @ ./~/pica/lib/resize_webgl.js 14:2-15 16:2-15

If we do require('pica/dist/pica') then it works but webpack outputs following warning:

WARNING in ./~/pica/dist/pica.js
Critical dependencies:
1:505-512 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/pica/dist/pica.js 1:505-512

What is the proper way to do it?

Implement new 'OffscreenCanvas' to enable WebGL processing in a webworker

It should be extremely trivial to make use of the new "OffscreenCanvas" feature to allow the webGL resizing to happen in a webworker.

Combining WebGL and webworkers in this manner would enable maximum speed, flexibility and responsiveness. It can currently tested by turning on the "about:config" flag "gfx.offscreencanvas.enabled" in Firefox or Firefox Nightly.

Further information can be found here:

https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas

With a lot more detail here:

https://hacks.mozilla.org/2016/01/webgl-off-the-main-thread/

Firefox has a completed implementation, behind an experimental flag, Chrome has it in development and MS is soon to start.

Premultiplied alpha?

Is pica expecting images with premultiplied alpha? It produces images images that look wrong when given pixels in a buffer that isn't premultiplied. Specifically, removing this line fixes the issue. According to the corresponding code from Skia, the pixels are premultiplied internally already, which that code assumes.

Here's an example image that causes the problem when its pixels are input directly without premultiplication. The resized output looks like this (with the alpha option turned on).

out

Apparently, canvas drawImage already premultiplies pixels even though getImageData is supposed to return non-premultiplied pixels (maybe browser image decoders do it automatically?), so it isn't an issue if you use a canvas as a source (only when the source is from drawImage maybe?).

There are two possible solutions to this: one is just documenting that the pixels need to be premultiplied before you can resize (more expensive), and the other is to make it work for non-premultiplied input. I'm not exactly sure what the fixAlpha function is supposed to fix, but it seems to work without it for me. Any ideas?

documentation?

Hi!

I'm having trouble finding out how to use this library. I went to the demo, copy/pasted some functions and it seems to work great, but I'm curious to know if there are other features I'm missing. e.g. cropping, is there any documentation anywhere?

Can't create Image from output of pica.resizeBuffer

Hi,
This is probably not an issue, something I'm doing wrong.

var originalWidth = this.image.width / 2;
var originalHeight = this.image.height / 2;

var canvas = document.createElement('canvas');
canvas.width = originalWidth;
canvas.height = originalHeight;
var ctx = canvas.getContext('2d');
//the image is loaded by now
ctx.drawImage(this.image, 0, 0, originalWidth, originalHeight);

var ratio = this.getRatio();

var picaOptions = {
    quality: aOptions.quality || 0,
    unsharpAmount: aOptions.unsharpAmount || 50,
    unsharpThreshold: aOptions.unsharpThreshold || 10,
    src: ctx.getImageData(0, 0, originalWidth, originalHeight).data,
    width: originalWidth,
    height: originalHeight,
    toWidth: aOptions.toWidth || aOptions.toHeight * ratio,
    toHeight: aOptions.toHeight || aOptions.toWidth * ratio
};

pica.resizeBuffer(picaOptions, function(err, output){
    if(err){
        return deferred.reject( err );
    }
    var blob = new Blob( [ output ], { type: "image/jpeg" } );
    var resizedImage = new Image();
    resizedImage.onload = deferred.resolve.bind(null, resizedImage);
    resizedImage.onerror = deferred.reject;
    resizedImage.src = window.URL.createObjectURL( blob );

});

it allways fires the onerror event on the image.
I don't know what i'm doing wrong, can you help me out please?

Memory leak issue

We are using pica for resizing images within our project. We noticed that there is a memory leak issue happening with this component and it was observed that it was happening in the component used to create the webworker (webworkify).
This component create a blob object of the source code then it will make a reference of this object using the createObjectURL function and pass it to a webworker.
This newly create ObjectURL is never released in the webworkify componant . It should use the function window.URL.revokeObjectURL in order to do so to fix this. Please suggest

Resize canvas into new canvas - whole content is black

Hi, I just want to resize a current canvas and didn't find examples. May be I am doing something wrong.

I have a valid canvas which works.

However, when I am trying to create a new empty canvas and resize into it with pica.resizeCanvas() I have a black canvas.

        const newCanvas = document.createElement('canvas');
        newCanvas.width = width;
        newCanvas.height = height;
        pica.resizeCanvas(canvas, newCanvas, 1, err => {
          console.log(err);
        });
        return newCanvas;

How to resize with .resizeBuffer?

Hi @puzrin !
Can I select an image from disk, resize it in memory somehow and then put into the final canvas, instead of using an intermediary canvas as source?
I don't really understand .resizeBuffer, Uint8Array and how to work with it...

Usage example

Hi, can you give an example, on what to do with the output (from the resizeBuffer() method) ? Specifically, I would like to convert it to something I can directly use with an HTML element.

Add support for WebWorkers on IE10+

When this line (in index.js) is being executed on IE11 mobile, I get SecurityError:

    wr = require('webworkify')(resizeWorker);

Looks like this needs some workaround.

2.0 pre-release tasks

  • Limit blur sigma range to 0.5-2.0
  • Recalculate borders with respect to blur sigma
  • return .resizeBuffer() with simple implementation
  • Disable webgl defaults in demo (use WW)
  • Readme update

Color changes after resizing.

So I'm using this resize to upload images to my server, but after resizing, the colors change a bit, or maybe the brightness. For example, a full white image, after resizing, the white turns a bit dark (#fdfdfd). I really need that the output image is equal to the source image, but size.

Thanks anyway, this proect is old! But still useful, good work!

Improve precision (idea)

  1. We could use double precision (16 bits per channel) for first pass. That requires more memory for intermediate result, but it can be compensated by interleaving convolve operations over circular buffer. See chromium skia sources for details (refs in readme).
  2. Also, it's possible to use double precision to pass data for unsharp function (but only if [1] done).

I don't know if it's really needed. But if someone find it funny - do it.

Blob URL leak

We have encountered a problem with Pica when processing large amounts of images (i.e. 1000+). When we resize multiple images through Pica, eventually it stops working, and when we look into the Network tab of the Developer Tools (on Chrome), we can see a corrupted Blob URL (empty).

I have taken a look at the Pica's source code and found that Pica creates Blob URLs using the URL.createObjectUrl to pass them to the worker constructor. There is a code like this:

    return new Worker(URL.createObjectURL(
        new Blob([src], { type: 'text/javascript' })
    ));

The documentation for URL.createObjectURL says that you have to release these URLs when they are no longer needed using the URL.revokeObjectURL:

https://developer.mozilla.org/en/docs/Web/API/URL/createObjectURL

However, in the code above, the created Blob URL is not released and apparently gets orphaned. As a result, when too many Blob URLs are created, the URL.createObjectURL starts failing (perhaps, it reaches some browser's limit for a number of Blob URLs).

I was going to patch Pica to save a reference to the Blob URL and revoke it when the worker is terminated, but I have updated to 2.0.2 and found out that the resizeBuffer method does not use workers anymore. So this update works for me, but you may want to fix it for the resizeCanvas method.

Pica not bundling properly with: ES6 imports/WebPack/RequireJS

Hey.

Title states the issue, and the error I receive was the following:

Error processing templates Path must be a string. Received { './lib/js/create_canvas.js': './lib/js/create_canvas_browser.js' }
-----------------------
[TypeError: Path must be a string. Received { './lib/js/create_canvas.js': './lib/js/create_canvas_browser.js' }]
-----------------------

Fixed it by redirecting the browser field in the package.json file to the final product:

"browser": "./dist/pica.min.js"

I am unaware of the consequences of this change for other bundling options though (SystemJS etc).

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.