109 lines
5.0 KiB
TypeScript
109 lines
5.0 KiB
TypeScript
|
export module ImageConver {
|
|||
|
export function ImageToBase64(Texture2D: cc.Texture2D): string {
|
|||
|
let image: ImageBitmap = Texture2D["_image"];
|
|||
|
let cv: HTMLCanvasElement = document.createElement("canvas");
|
|||
|
let context: CanvasRenderingContext2D = cv.getContext("2d");
|
|||
|
cv.width = image.width || 128;
|
|||
|
cv.height = image.height || 128;
|
|||
|
context.drawImage(image, 0, 0, image.width || 128, image.height || 128);
|
|||
|
let DataURL: string = cv.toDataURL();
|
|||
|
return DataURL;
|
|||
|
}
|
|||
|
export function Base64toBlob(b64Data: any, contentType: string = "image/png", sliceSize: number = 512): Blob {
|
|||
|
let byteCharacters: string = atob(b64Data.substring(b64Data.indexOf(",") + 1));
|
|||
|
const byteArrays: any[] = [];
|
|||
|
for (let offset: number = 0; offset < byteCharacters.length; offset += sliceSize) {
|
|||
|
const slice: string = byteCharacters.slice(offset, offset + sliceSize);
|
|||
|
|
|||
|
const byteNumbers: any[] = new Array(slice.length);
|
|||
|
for (let i: number = 0; i < slice.length; i++) {
|
|||
|
byteNumbers[i] = slice.charCodeAt(i);
|
|||
|
}
|
|||
|
const byteArray: Uint8Array = new Uint8Array(byteNumbers);
|
|||
|
byteArrays.push(byteArray);
|
|||
|
}
|
|||
|
const blob: Blob = new Blob(byteArrays, { type: contentType });
|
|||
|
return blob;
|
|||
|
}
|
|||
|
|
|||
|
export function BlobToImageNode(BlobData: Blob, node: cc.Node): void {
|
|||
|
let reader: FileReader = new FileReader();
|
|||
|
reader.onloadend = function (): void {
|
|||
|
ImageConver.Base64ToImageNode(reader.result + "", node);
|
|||
|
};
|
|||
|
reader.readAsDataURL(BlobData);
|
|||
|
}
|
|||
|
|
|||
|
export function Base64ToImageNode(base64: string, node: cc.Node): void {
|
|||
|
let image: HTMLImageElement = new Image();
|
|||
|
image.src = base64;
|
|||
|
image.onload = function (): void {
|
|||
|
let texture: cc.Texture2D = new cc.Texture2D();
|
|||
|
texture.initWithElement(image);
|
|||
|
texture.handleLoadedTexture();
|
|||
|
let spriteFrame: cc.SpriteFrame = new cc.SpriteFrame(texture);
|
|||
|
let sprite: cc.Sprite = node.addComponent(cc.Sprite);
|
|||
|
sprite.spriteFrame = spriteFrame;
|
|||
|
return;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
export function Node2Base64(nodeCapture: cc.Node): string {
|
|||
|
let nodeCamera: cc.Node = new cc.Node();
|
|||
|
nodeCamera.parent = cc.find("Canvas");
|
|||
|
let camera: cc.Camera = nodeCamera.addComponent(cc.Camera);
|
|||
|
|
|||
|
let position: cc.Vec2 = nodeCapture.getPosition();
|
|||
|
let width: number = nodeCapture.width;
|
|||
|
let height: number = nodeCapture.height;
|
|||
|
|
|||
|
// 当 alignWithScreen 为 true 的时候,摄像机会自动将视窗大小调整为整个屏幕的大小。如果想要完全自由地控制摄像机,则需要将 alignWithScreen 设置为 false。(v2.2.1 新增)
|
|||
|
camera.alignWithScreen = false;
|
|||
|
// 设置摄像机的投影模式是正交(true)还是透视(false)模式
|
|||
|
camera.ortho = true;
|
|||
|
// 摄像机在正交投影模式下的视窗大小。该属性在 alignWithScreen 设置为 false 时生效。
|
|||
|
camera.orthoSize = height / 2;
|
|||
|
|
|||
|
let texture: cc.RenderTexture = new cc.RenderTexture();
|
|||
|
// 如果截图内容中不包含 Mask 组件,可以不用传递第三个参数
|
|||
|
texture.initWithSize(width, height);
|
|||
|
|
|||
|
// 如果设置了 targetTexture,那么摄像机渲染的内容不会输出到屏幕上,而是会渲染到 targetTexture 上。
|
|||
|
camera.targetTexture = texture;
|
|||
|
|
|||
|
// 创建画布
|
|||
|
let canvas: HTMLCanvasElement = document.createElement("canvas");
|
|||
|
canvas.width = width;
|
|||
|
canvas.height = height;
|
|||
|
|
|||
|
let ctx: CanvasRenderingContext2D = canvas.getContext("2d");
|
|||
|
|
|||
|
nodeCapture.setPosition(cc.Vec2.ZERO);
|
|||
|
// 渲染一次摄像机,即更新一次内容到 RenderTexture 中
|
|||
|
camera.render(nodeCapture);
|
|||
|
nodeCapture.setPosition(position);
|
|||
|
|
|||
|
// 从 render texture 读取像素数据,数据类型为 RGBA 格式的 Uint8Array 数组。
|
|||
|
// 默认每次调用此函数会生成一个大小为 (长 x 高 x 4) 的 Uint8Array。
|
|||
|
let data: Uint8Array = texture.readPixels();
|
|||
|
// write the render data
|
|||
|
// PNG 中 1 像素 = 32 bit(RGBA),1 byte = 8 bit,所以 1 像素 = 4 byte
|
|||
|
// 每行 width 像素,即 width * 4 字节
|
|||
|
let rowBytes: number = width * 4;
|
|||
|
for (let row: number = 0; row < height; row++) {
|
|||
|
// RenderTexture 得到的纹理是上下翻转的
|
|||
|
let srow: number = height - 1 - row;
|
|||
|
let imageData: ImageData = ctx.createImageData(width, 1);
|
|||
|
let start: number = srow * width * 4;
|
|||
|
for (let i: number = 0; i < rowBytes; i++) {
|
|||
|
imageData.data[i] = data[start + i];
|
|||
|
}
|
|||
|
|
|||
|
ctx.putImageData(imageData, 0, row);
|
|||
|
}
|
|||
|
|
|||
|
let dataURL: string = canvas.toDataURL("image/png");
|
|||
|
|
|||
|
return dataURL;
|
|||
|
}
|
|||
|
}
|