ppu-ocv
Version:
A type-safe, modular, chainable image processing library built on top of OpenCV.js with a fluent API leveraging pipeline processing.
1 lines • 4.99 kB
JavaScript
class SkiaContext2DLike{_surface;_skCanvas;_path=null;_parentCanvas;strokeStyle="#000000";fillStyle="#000000";lineWidth=1;constructor(surface,parentCanvas){this._surface=surface;this._skCanvas=surface.getCanvas();this._parentCanvas=parentCanvas}get canvas(){return this._parentCanvas}getImageData(sx,sy,sw,sh){const{Skia,AlphaType,ColorType}=getSkia();let snapshot=this._surface.makeImageSnapshot();let info={width:sw,height:sh,colorType:ColorType.RGBA_8888,alphaType:AlphaType.Unpremul};let pixels=snapshot.readPixels(sx,sy,info);if(!pixels){throw new Error(`SkiaContext2DLike.getImageData: readPixels returned null `+`(surface may have been released, region: ${sx},${sy} ${sw}×${sh})`)}return{data:new Uint8ClampedArray(pixels.buffer,pixels.byteOffset,pixels.byteLength),width:sw,height:sh}}putImageData(imageData,dx,dy){const{Skia,AlphaType,ColorType}=getSkia();const{data,width,height}=imageData;let bytes=new Uint8Array(data.buffer,data.byteOffset,data.byteLength);let skData=Skia.Data.fromBytes(bytes);let img=Skia.Image.MakeImage({width,height,colorType:ColorType.RGBA_8888,alphaType:AlphaType.Unpremul},skData,width*4);if(!img){throw new Error("SkiaContext2DLike.putImageData: MakeImage returned null")}this._skCanvas.drawImage(img,dx,dy);this._surface.flush()}createImageData(width,height){return{data:new Uint8ClampedArray(width*height*4),width,height}}drawImage(...args){let src=args[0];let img;if(src instanceof SkiaCanvasLike){img=src._surface.makeImageSnapshot()}else if(src&&typeof src._skiaImage!=="undefined"){img=src._skiaImage}else{throw new Error("SkiaContext2DLike.drawImage: source must be a SkiaCanvasLike (use mobilePlatform.loadImage)")}if(args.length===3){this._skCanvas.drawImage(img,args[1],args[2])}else if(args.length===5){const{Skia}=getSkia();let dstRect=Skia.XYWHRect(args[1],args[2],args[3],args[4]);let srcRect=Skia.XYWHRect(0,0,img.width(),img.height());this._skCanvas.drawImageRect(img,srcRect,dstRect,Skia.Paint())}else if(args.length===9){const{Skia}=getSkia();let srcRect=Skia.XYWHRect(args[1],args[2],args[3],args[4]);let dstRect=Skia.XYWHRect(args[5],args[6],args[7],args[8]);this._skCanvas.drawImageRect(img,srcRect,dstRect,Skia.Paint())}else{throw new Error(`SkiaContext2DLike.drawImage: unsupported argument count (${args.length})`)}this._surface.flush()}fillRect(x,y,w,h){const{Skia}=getSkia();let paint=Skia.Paint();paint.setColor(Skia.Color(this.fillStyle));this._skCanvas.drawRect(Skia.XYWHRect(x,y,w,h),paint);this._surface.flush()}strokeRect(x,y,w,h){const{Skia,PaintStyle}=getSkia();let paint=Skia.Paint();paint.setColor(Skia.Color(this.strokeStyle));paint.setStyle(PaintStyle.Stroke);paint.setStrokeWidth(this.lineWidth);this._skCanvas.drawRect(Skia.XYWHRect(x,y,w,h),paint);this._surface.flush()}beginPath(){const{Skia}=getSkia();this._path=Skia.Path.Make()}closePath(){this._path?.close()}moveTo(x,y){this._path?.moveTo(x,y)}lineTo(x,y){this._path?.lineTo(x,y)}stroke(){if(!this._path)return;const{Skia,PaintStyle}=getSkia();let paint=Skia.Paint();paint.setColor(Skia.Color(this.strokeStyle));paint.setStyle(PaintStyle.Stroke);paint.setStrokeWidth(this.lineWidth);this._skCanvas.drawPath(this._path,paint);this._surface.flush()}save(){this._skCanvas.save()}restore(){this._skCanvas.restore()}translate(x,y){this._skCanvas.translate(x,y)}rotate(angle){this._skCanvas.rotate(angle*180/Math.PI,0,0)}}class SkiaCanvasLike{_surface;_ctx=null;constructor(surface){this._surface=surface}get width(){return this._surface.width()}get height(){return this._surface.height()}getContext(_contextId){if(!this._ctx){this._ctx=new SkiaContext2DLike(this._surface,this)}return this._ctx}}let _skia=null;function getSkia(){if(_skia)return _skia;_skia=require("@shopify/react-native-skia");return _skia}export let mobilePlatform={createCanvas(width,height){const{Skia}=getSkia();let surface=Skia.Surface.Make(width,height);if(!surface){throw new Error(`mobilePlatform.createCanvas: Skia.Surface.Make(${width}, ${height}) returned null. `+"Ensure @shopify/react-native-skia is correctly installed and Skia is initialised.")}return new SkiaCanvasLike(surface)},async loadImage(source){const{Skia,AlphaType,ColorType}=getSkia();let skData;if(source instanceof ArrayBuffer){skData=Skia.Data.fromBytes(new Uint8Array(source))}else if(typeof source==="string"){skData=await Skia.Data.fromURI(source)}else{throw new Error("mobilePlatform.loadImage: source must be an ArrayBuffer or string URI")}let image=Skia.Image.MakeImageFromEncoded(skData);if(!image){throw new Error("mobilePlatform.loadImage: MakeImageFromEncoded returned null — "+"the image data may be corrupt or in an unsupported format.")}let width=image.width();let height=image.height();let surface=Skia.Surface.Make(width,height);if(!surface){throw new Error("mobilePlatform.loadImage: Skia.Surface.Make returned null")}let canvas=surface.getCanvas();canvas.drawImage(image,0,0);surface.flush();return new SkiaCanvasLike(surface)},isCanvas(value){return value instanceof SkiaCanvasLike}};