extract.js 8.8 KB

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