extract.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*!
  2. * @pixi/extract - v6.5.10
  3. * Compiled Thu, 06 Jul 2023 15:25:11 UTC
  4. *
  5. * @pixi/extract is licensed under the MIT License.
  6. * http://www.opensource.org/licenses/mit-license
  7. */
  8. 'use strict';
  9. Object.defineProperty(exports, '__esModule', { value: true });
  10. var constants = require('@pixi/constants');
  11. var utils = require('@pixi/utils');
  12. var math = require('@pixi/math');
  13. var core = require('@pixi/core');
  14. var TEMP_RECT = new math.Rectangle();
  15. var BYTES_PER_PIXEL = 4;
  16. /**
  17. * This class provides renderer-specific plugins for exporting content from a renderer.
  18. * For instance, these plugins can be used for saving an Image, Canvas element or for exporting the raw image data (pixels).
  19. *
  20. * Do not instantiate these plugins directly. It is available from the `renderer.plugins` property.
  21. * See {@link PIXI.CanvasRenderer#plugins} or {@link PIXI.Renderer#plugins}.
  22. * @example
  23. * // Create a new app (will auto-add extract plugin to renderer)
  24. * const app = new PIXI.Application();
  25. *
  26. * // Draw a red circle
  27. * const graphics = new PIXI.Graphics()
  28. * .beginFill(0xFF0000)
  29. * .drawCircle(0, 0, 50);
  30. *
  31. * // Render the graphics as an HTMLImageElement
  32. * const image = app.renderer.plugins.extract.image(graphics);
  33. * document.body.appendChild(image);
  34. * @memberof PIXI
  35. */
  36. var Extract = /** @class */ (function () {
  37. /**
  38. * @param renderer - A reference to the current renderer
  39. */
  40. function Extract(renderer) {
  41. this.renderer = renderer;
  42. }
  43. /**
  44. * Will return a HTML Image of the target
  45. * @param target - A displayObject or renderTexture
  46. * to convert. If left empty will use the main renderer
  47. * @param format - Image format, e.g. "image/jpeg" or "image/webp".
  48. * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92.
  49. * @returns - HTML Image of the target
  50. */
  51. Extract.prototype.image = function (target, format, quality) {
  52. var image = new Image();
  53. image.src = this.base64(target, format, quality);
  54. return image;
  55. };
  56. /**
  57. * Will return a base64 encoded string of this target. It works by calling
  58. * `Extract.getCanvas` and then running toDataURL on that.
  59. * @param target - A displayObject or renderTexture
  60. * to convert. If left empty will use the main renderer
  61. * @param format - Image format, e.g. "image/jpeg" or "image/webp".
  62. * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92.
  63. * @returns - A base64 encoded string of the texture.
  64. */
  65. Extract.prototype.base64 = function (target, format, quality) {
  66. return this.canvas(target).toDataURL(format, quality);
  67. };
  68. /**
  69. * Creates a Canvas element, renders this target to it and then returns it.
  70. * @param target - A displayObject or renderTexture
  71. * to convert. If left empty will use the main renderer
  72. * @param frame - The frame the extraction is restricted to.
  73. * @returns - A Canvas element with the texture rendered on.
  74. */
  75. Extract.prototype.canvas = function (target, frame) {
  76. var _a = this._rawPixels(target, frame), pixels = _a.pixels, width = _a.width, height = _a.height, flipY = _a.flipY;
  77. var canvasBuffer = new utils.CanvasRenderTarget(width, height, 1);
  78. // Add the pixels to the canvas
  79. var canvasData = canvasBuffer.context.getImageData(0, 0, width, height);
  80. Extract.arrayPostDivide(pixels, canvasData.data);
  81. canvasBuffer.context.putImageData(canvasData, 0, 0);
  82. // Flipping pixels
  83. if (flipY) {
  84. var target_1 = new utils.CanvasRenderTarget(canvasBuffer.width, canvasBuffer.height, 1);
  85. target_1.context.scale(1, -1);
  86. // We can't render to itself because we should be empty before render.
  87. target_1.context.drawImage(canvasBuffer.canvas, 0, -height);
  88. canvasBuffer.destroy();
  89. canvasBuffer = target_1;
  90. }
  91. // Send the canvas back
  92. return canvasBuffer.canvas;
  93. };
  94. /**
  95. * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA
  96. * order, with integer values between 0 and 255 (included).
  97. * @param target - A displayObject or renderTexture
  98. * to convert. If left empty will use the main renderer
  99. * @param frame - The frame the extraction is restricted to.
  100. * @returns - One-dimensional array containing the pixel data of the entire texture
  101. */
  102. Extract.prototype.pixels = function (target, frame) {
  103. var pixels = this._rawPixels(target, frame).pixels;
  104. Extract.arrayPostDivide(pixels, pixels);
  105. return pixels;
  106. };
  107. Extract.prototype._rawPixels = function (target, frame) {
  108. var renderer = this.renderer;
  109. var resolution;
  110. var flipY = false;
  111. var renderTexture;
  112. var generated = false;
  113. if (target) {
  114. if (target instanceof core.RenderTexture) {
  115. renderTexture = target;
  116. }
  117. else {
  118. var multisample = renderer.context.webGLVersion >= 2 ? renderer.multisample : constants.MSAA_QUALITY.NONE;
  119. renderTexture = this.renderer.generateTexture(target, { multisample: multisample });
  120. if (multisample !== constants.MSAA_QUALITY.NONE) {
  121. // Resolve the multisampled texture to a non-multisampled texture
  122. var resolvedTexture = core.RenderTexture.create({
  123. width: renderTexture.width,
  124. height: renderTexture.height,
  125. });
  126. renderer.framebuffer.bind(renderTexture.framebuffer);
  127. renderer.framebuffer.blit(resolvedTexture.framebuffer);
  128. renderer.framebuffer.bind(null);
  129. renderTexture.destroy(true);
  130. renderTexture = resolvedTexture;
  131. }
  132. generated = true;
  133. }
  134. }
  135. if (renderTexture) {
  136. resolution = renderTexture.baseTexture.resolution;
  137. frame = frame !== null && frame !== void 0 ? frame : renderTexture.frame;
  138. flipY = false;
  139. renderer.renderTexture.bind(renderTexture);
  140. }
  141. else {
  142. resolution = renderer.resolution;
  143. if (!frame) {
  144. frame = TEMP_RECT;
  145. frame.width = renderer.width;
  146. frame.height = renderer.height;
  147. }
  148. flipY = true;
  149. renderer.renderTexture.bind(null);
  150. }
  151. var width = Math.round(frame.width * resolution);
  152. var height = Math.round(frame.height * resolution);
  153. var pixels = new Uint8Array(BYTES_PER_PIXEL * width * height);
  154. // Read pixels to the array
  155. var gl = renderer.gl;
  156. gl.readPixels(Math.round(frame.x * resolution), Math.round(frame.y * resolution), width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
  157. if (generated) {
  158. renderTexture.destroy(true);
  159. }
  160. return { pixels: pixels, width: width, height: height, flipY: flipY };
  161. };
  162. /** Destroys the extract. */
  163. Extract.prototype.destroy = function () {
  164. this.renderer = null;
  165. };
  166. /**
  167. * Takes premultiplied pixel data and produces regular pixel data
  168. * @private
  169. * @param pixels - array of pixel data
  170. * @param out - output array
  171. */
  172. Extract.arrayPostDivide = function (pixels, out) {
  173. for (var i = 0; i < pixels.length; i += 4) {
  174. var alpha = out[i + 3] = pixels[i + 3];
  175. if (alpha !== 0) {
  176. out[i] = Math.round(Math.min(pixels[i] * 255.0 / alpha, 255.0));
  177. out[i + 1] = Math.round(Math.min(pixels[i + 1] * 255.0 / alpha, 255.0));
  178. out[i + 2] = Math.round(Math.min(pixels[i + 2] * 255.0 / alpha, 255.0));
  179. }
  180. else {
  181. out[i] = pixels[i];
  182. out[i + 1] = pixels[i + 1];
  183. out[i + 2] = pixels[i + 2];
  184. }
  185. }
  186. };
  187. /** @ignore */
  188. Extract.extension = {
  189. name: 'extract',
  190. type: core.ExtensionType.RendererPlugin,
  191. };
  192. return Extract;
  193. }());
  194. exports.Extract = Extract;
  195. //# sourceMappingURL=extract.js.map