| 1 |
- {"version":3,"file":"extract.mjs","sources":["../../src/Extract.ts"],"sourcesContent":["import { MSAA_QUALITY } from '@pixi/constants';\nimport { CanvasRenderTarget } from '@pixi/utils';\nimport { Rectangle } from '@pixi/math';\nimport { ExtensionType, RenderTexture } from '@pixi/core';\n\nimport type { Renderer, IRendererPlugin, ExtensionMetadata } from '@pixi/core';\nimport type { DisplayObject } from '@pixi/display';\n\nconst TEMP_RECT = new Rectangle();\nconst BYTES_PER_PIXEL = 4;\n\n/**\n * this interface is used to extract only a single pixel of Render Texture or Display Object\n * if you use this Interface all fields is required\n * @deprecated\n * @example\n * test: PixelExtractOptions = { x: 15, y: 20, resolution: 4, width: 10, height: 10 }\n */\nexport interface PixelExtractOptions\n{\n x: number,\n y: number,\n height: number,\n resolution: number,\n width: number\n}\n\n/**\n * This class provides renderer-specific plugins for exporting content from a renderer.\n * For instance, these plugins can be used for saving an Image, Canvas element or for exporting the raw image data (pixels).\n *\n * Do not instantiate these plugins directly. It is available from the `renderer.plugins` property.\n * See {@link PIXI.CanvasRenderer#plugins} or {@link PIXI.Renderer#plugins}.\n * @example\n * // Create a new app (will auto-add extract plugin to renderer)\n * const app = new PIXI.Application();\n *\n * // Draw a red circle\n * const graphics = new PIXI.Graphics()\n * .beginFill(0xFF0000)\n * .drawCircle(0, 0, 50);\n *\n * // Render the graphics as an HTMLImageElement\n * const image = app.renderer.plugins.extract.image(graphics);\n * document.body.appendChild(image);\n * @memberof PIXI\n */\n\nexport class Extract implements IRendererPlugin\n{\n /** @ignore */\n static extension: ExtensionMetadata = {\n name: 'extract',\n type: ExtensionType.RendererPlugin,\n };\n\n private renderer: Renderer;\n\n /**\n * @param renderer - A reference to the current renderer\n */\n constructor(renderer: Renderer)\n {\n this.renderer = renderer;\n }\n\n /**\n * Will return a HTML Image of the target\n * @param target - A displayObject or renderTexture\n * to convert. If left empty will use the main renderer\n * @param format - Image format, e.g. \"image/jpeg\" or \"image/webp\".\n * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92.\n * @returns - HTML Image of the target\n */\n public image(target: DisplayObject | RenderTexture, format?: string, quality?: number): HTMLImageElement\n {\n const image = new Image();\n\n image.src = this.base64(target, format, quality);\n\n return image;\n }\n\n /**\n * Will return a base64 encoded string of this target. It works by calling\n * `Extract.getCanvas` and then running toDataURL on that.\n * @param target - A displayObject or renderTexture\n * to convert. If left empty will use the main renderer\n * @param format - Image format, e.g. \"image/jpeg\" or \"image/webp\".\n * @param quality - JPEG or Webp compression from 0 to 1. Default is 0.92.\n * @returns - A base64 encoded string of the texture.\n */\n public base64(target: DisplayObject | RenderTexture, format?: string, quality?: number): string\n {\n return this.canvas(target).toDataURL(format, quality);\n }\n\n /**\n * Creates a Canvas element, renders this target to it and then returns it.\n * @param target - A displayObject or renderTexture\n * to convert. If left empty will use the main renderer\n * @param frame - The frame the extraction is restricted to.\n * @returns - A Canvas element with the texture rendered on.\n */\n public canvas(target?: DisplayObject | RenderTexture, frame?: Rectangle): HTMLCanvasElement\n {\n const { pixels, width, height, flipY } = this._rawPixels(target, frame);\n\n let canvasBuffer = new CanvasRenderTarget(width, height, 1);\n\n // Add the pixels to the canvas\n const canvasData = canvasBuffer.context.getImageData(0, 0, width, height);\n\n Extract.arrayPostDivide(pixels, canvasData.data);\n\n canvasBuffer.context.putImageData(canvasData, 0, 0);\n\n // Flipping pixels\n if (flipY)\n {\n const target = new CanvasRenderTarget(canvasBuffer.width, canvasBuffer.height, 1);\n\n target.context.scale(1, -1);\n\n // We can't render to itself because we should be empty before render.\n target.context.drawImage(canvasBuffer.canvas, 0, -height);\n\n canvasBuffer.destroy();\n canvasBuffer = target;\n }\n\n // Send the canvas back\n return canvasBuffer.canvas;\n }\n\n /**\n * Will return a one-dimensional array containing the pixel data of the entire texture in RGBA\n * order, with integer values between 0 and 255 (included).\n * @param target - A displayObject or renderTexture\n * to convert. If left empty will use the main renderer\n * @param frame - The frame the extraction is restricted to.\n * @returns - One-dimensional array containing the pixel data of the entire texture\n */\n public pixels(target?: DisplayObject | RenderTexture, frame?: Rectangle | PixelExtractOptions): Uint8Array\n {\n const { pixels } = this._rawPixels(target, frame as Rectangle);\n\n Extract.arrayPostDivide(pixels, pixels);\n\n return pixels;\n }\n\n private _rawPixels(target?: DisplayObject | RenderTexture, frame?: Rectangle): {\n pixels: Uint8Array, width: number, height: number, flipY: boolean,\n }\n {\n const renderer = this.renderer;\n let resolution;\n let flipY = false;\n let renderTexture;\n let generated = false;\n\n if (target)\n {\n if (target instanceof RenderTexture)\n {\n renderTexture = target;\n }\n else\n {\n const multisample = renderer.context.webGLVersion >= 2 ? renderer.multisample : MSAA_QUALITY.NONE;\n\n renderTexture = this.renderer.generateTexture(target, { multisample });\n\n if (multisample !== MSAA_QUALITY.NONE)\n {\n // Resolve the multisampled texture to a non-multisampled texture\n const resolvedTexture = RenderTexture.create({\n width: renderTexture.width,\n height: renderTexture.height,\n });\n\n renderer.framebuffer.bind(renderTexture.framebuffer);\n renderer.framebuffer.blit(resolvedTexture.framebuffer);\n renderer.framebuffer.bind(null);\n\n renderTexture.destroy(true);\n renderTexture = resolvedTexture;\n }\n\n generated = true;\n }\n }\n\n if (renderTexture)\n {\n resolution = renderTexture.baseTexture.resolution;\n frame = frame ?? renderTexture.frame;\n flipY = false;\n renderer.renderTexture.bind(renderTexture);\n }\n else\n {\n resolution = renderer.resolution;\n\n if (!frame)\n {\n frame = TEMP_RECT;\n frame.width = renderer.width;\n frame.height = renderer.height;\n }\n\n flipY = true;\n renderer.renderTexture.bind(null);\n }\n\n const width = Math.round(frame.width * resolution);\n const height = Math.round(frame.height * resolution);\n\n const pixels = new Uint8Array(BYTES_PER_PIXEL * width * height);\n\n // Read pixels to the array\n const gl = renderer.gl;\n\n gl.readPixels(\n Math.round(frame.x * resolution),\n Math.round(frame.y * resolution),\n width,\n height,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n pixels\n );\n\n if (generated)\n {\n renderTexture.destroy(true);\n }\n\n return { pixels, width, height, flipY };\n }\n\n /** Destroys the extract. */\n public destroy(): void\n {\n this.renderer = null;\n }\n\n /**\n * Takes premultiplied pixel data and produces regular pixel data\n * @private\n * @param pixels - array of pixel data\n * @param out - output array\n */\n static arrayPostDivide(\n pixels: number[] | Uint8Array | Uint8ClampedArray, out: number[] | Uint8Array | Uint8ClampedArray\n ): void\n {\n for (let i = 0; i < pixels.length; i += 4)\n {\n const alpha = out[i + 3] = pixels[i + 3];\n\n if (alpha !== 0)\n {\n out[i] = Math.round(Math.min(pixels[i] * 255.0 / alpha, 255.0));\n out[i + 1] = Math.round(Math.min(pixels[i + 1] * 255.0 / alpha, 255.0));\n out[i + 2] = Math.round(Math.min(pixels[i + 2] * 255.0 / alpha, 255.0));\n }\n else\n {\n out[i] = pixels[i];\n out[i + 1] = pixels[i + 1];\n out[i + 2] = pixels[i + 2];\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|