* Resizes the image to a given width and height. * * The image's original aspect ratio can be kept by passing 0 for either * `width` or `height`. For example, calling `img.resize(50, 0)` on an image * that was 500 × 300 pixels will resize it to 50 × 30 pixels. * * @para
(width, height)
| 722 | * } |
| 723 | */ |
| 724 | resize(width, height) { |
| 725 | // Copy contents to a temporary canvas, resize the original |
| 726 | // and then copy back. |
| 727 | // |
| 728 | // There is a faster approach that involves just one copy and swapping the |
| 729 | // this.canvas reference. We could switch to that approach if (as i think |
| 730 | // is the case) there an expectation that the user would not hold a |
| 731 | // reference to the backing canvas of a p5.Image. But since we do not |
| 732 | // enforce that at the moment, I am leaving in the slower, but safer |
| 733 | // implementation. |
| 734 | |
| 735 | // auto-resize |
| 736 | if (width === 0 && height === 0) { |
| 737 | width = this.canvas.width; |
| 738 | height = this.canvas.height; |
| 739 | } else if (width === 0) { |
| 740 | width = this.canvas.width * height / this.canvas.height; |
| 741 | } else if (height === 0) { |
| 742 | height = this.canvas.height * width / this.canvas.width; |
| 743 | } |
| 744 | |
| 745 | width = Math.floor(width); |
| 746 | height = Math.floor(height); |
| 747 | |
| 748 | const tempCanvas = document.createElement('canvas'); |
| 749 | tempCanvas.width = width; |
| 750 | tempCanvas.height = height; |
| 751 | |
| 752 | if (this.gifProperties) { |
| 753 | const props = this.gifProperties; |
| 754 | //adapted from github.com/LinusU/resize-image-data |
| 755 | const nearestNeighbor = (src, dst) => { |
| 756 | let pos = 0; |
| 757 | for (let y = 0; y < dst.height; y++) { |
| 758 | for (let x = 0; x < dst.width; x++) { |
| 759 | const srcX = Math.floor(x * src.width / dst.width); |
| 760 | const srcY = Math.floor(y * src.height / dst.height); |
| 761 | let srcPos = (srcY * src.width + srcX) * 4; |
| 762 | dst.data[pos++] = src.data[srcPos++]; // R |
| 763 | dst.data[pos++] = src.data[srcPos++]; // G |
| 764 | dst.data[pos++] = src.data[srcPos++]; // B |
| 765 | dst.data[pos++] = src.data[srcPos++]; // A |
| 766 | } |
| 767 | } |
| 768 | }; |
| 769 | for (let i = 0; i < props.numFrames; i++) { |
| 770 | const resizedImageData = this.drawingContext.createImageData( |
| 771 | width, |
| 772 | height |
| 773 | ); |
| 774 | nearestNeighbor(props.frames[i].image, resizedImageData); |
| 775 | props.frames[i].image = resizedImageData; |
| 776 | } |
| 777 | } |
| 778 | |
| 779 | tempCanvas.getContext('2d').drawImage( |
| 780 | this.canvas, |
| 781 | 0, 0, this.canvas.width, this.canvas.height, |
no test coverage detected