public void ReleaseBitmapPixelsWasInvoked() { bool released = false; var onRelease = new SKBitmapReleaseDelegate((addr, ctx) => { Marshal.FreeCoTaskMem(addr); released = true; Assert.AreEqual("RELEASING!", ctx); }); using (var bitmap = new SKBitmap()) { var info = new SKImageInfo(1, 1); var pixels = Marshal.AllocCoTaskMem(info.BytesSize); bitmap.InstallPixels(info, pixels, info.RowBytes, null, onRelease, "RELEASING!"); } Assert.True(released, "The SKBitmapReleaseDelegate was not called."); }
private void DrawInputTensor(SKCanvas canvas) { var bitmap = new SKBitmap(); var gcHandle = GCHandle.Alloc(colors, GCHandleType.Pinned); var info = new SKImageInfo( TensorflowLiteService.ModelInputSize, TensorflowLiteService.ModelInputSize, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul); bitmap.InstallPixels( info, gcHandle.AddrOfPinnedObject(), info.RowBytes, (address, context) => { gcHandle.Free(); }); canvas.DrawBitmap(bitmap, new SKPoint(0, 0)); }
private static SKData CreateFractalImageData(FractalInput input) { FractalInit initdata = InitData(0, 0, input.zoom); // Create a surface. var info = new SKImageInfo(initdata.width, initdata.height, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul); //using (var surface = SKSurface.Create(info)) { var mandelbrot = new FractalMandelbrot(initdata); var bytes = mandelbrot.compute(); // the the canvas and properties //var canvas = surface.Canvas; //for (int y = 0; y < initdata.height; y++) //{ // for (int x = 0; x < initdata.width; x++) // { // int index = 4 * (x + y * initdata.width); // canvas.DrawPoint(new SKPoint(x, y), new SKColor(bytes[index + 2], bytes[index + 1], bytes[index])); // } //} // Optimization taken from https://github.com/mono/SkiaSharp/issues/416 // create an empty bitmap var bitmap = new SKBitmap(); // pin the managed array so that the GC doesn't move it var gcHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); // install the pixels with the color type of the pixel data bitmap.InstallPixels(info, gcHandle.AddrOfPinnedObject(), info.RowBytes, delegate { gcHandle.Free(); }, null); //using (var image = surface.Snapshot()) using (var image = SKImage.FromBitmap(bitmap)) { SKData data = image.Encode(SKEncodedImageFormat.Png, 100); return(data); } } }
private unsafe void DecodeFrame(FastJavaByteArray fastArray) { if (input == null) { width = cameraController.LastCameraDisplayWidth; height = cameraController.LastCameraDisplayHeight; cDegrees = cameraController.LastCameraDisplayOrientationDegree; imageData = new int[width * height]; imageGCHandle = GCHandle.Alloc(imageData, GCHandleType.Pinned); imageIntPtr = imageGCHandle.AddrOfPinnedObject(); input = new SKBitmap(new SKImageInfo(width, height, SKColorType.Rgba8888)); input.InstallPixels(input.Info, imageIntPtr); } var pY = fastArray.Raw; var pUV = pY + width * height; stopwatch.Restart(); YuvHelper.ConvertYUV420SPToARGB8888(pY, pUV, (int *)imageIntPtr, width, height); stopwatch.Stop(); Stats.YUV2RGBElapsedMs = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); input.ScalePixels(inputScaled, SKFilterQuality.None); RotateBitmap(inputScaled, cDegrees); stopwatch.Stop(); Stats.ResizeAndRotateElapsedMs = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); tfService.Recognize(colors, colorCount); stopwatch.Stop(); Stats.InterpreterElapsedMs = stopwatch.ElapsedMilliseconds; MainActivity.ReloadCanvas(); }
public SKBitmap GenerateBitmap() { Reader.BaseStream.Position = DataOffset; var width = NonPow2Width > 0 ? NonPow2Width : Width; var height = NonPow2Height > 0 ? NonPow2Height : Height; var imageInfo = new SKImageInfo(width, height, SKColorType.Bgra8888, SKAlphaType.Unpremul); Span <byte> data = new byte[imageInfo.RowBytes * imageInfo.Height]; SkipMipmaps(); switch (Format) { case VTexFormat.DXT1: TextureDecompressors.UncompressDXT1(imageInfo, GetDecompressedBuffer(), data, Width, Height); break; case VTexFormat.DXT5: var yCoCg = false; var normalize = false; var invert = false; if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies)) { var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies]; yCoCg = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image YCoCg Conversion"); normalize = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image NormalizeNormals"); invert = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version LegacySource1InvertNormals"); } TextureDecompressors.UncompressDXT5(imageInfo, GetDecompressedBuffer(), data, Width, Height, yCoCg, normalize, invert); break; case VTexFormat.I8: return(TextureDecompressors.ReadI8(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA8888: return(TextureDecompressors.ReadRGBA8888(GetDecompressedBuffer(), Width, Height)); case VTexFormat.R16: return(TextureDecompressors.ReadR16(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG1616: return(TextureDecompressors.ReadRG1616(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA16161616: TextureDecompressors.ReadRGBA16161616(imageInfo, GetDecompressedBuffer(), data); break; case VTexFormat.R16F: return(TextureDecompressors.ReadR16F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG1616F: return(TextureDecompressors.ReadRG1616F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA16161616F: TextureDecompressors.ReadRGBA16161616F(imageInfo, GetDecompressedBuffer(), data); break; case VTexFormat.R32F: return(TextureDecompressors.ReadR32F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG3232F: return(TextureDecompressors.ReadRG3232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGB323232F: return(TextureDecompressors.ReadRGB323232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA32323232F: return(TextureDecompressors.ReadRGBA32323232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.IA88: return(TextureDecompressors.ReadIA88(GetDecompressedBuffer(), Width, Height)); // TODO: Are we sure DXT5 and RGBA8888 are just raw buffers? case VTexFormat.JPEG_DXT5: case VTexFormat.JPEG_RGBA8888: case VTexFormat.PNG_DXT5: case VTexFormat.PNG_RGBA8888: return(ReadBuffer()); case VTexFormat.ETC2: var etc = new Etc.EtcDecoder(); var rewriteMeProperlyPlease = new byte[data.Length]; // TODO etc.DecompressETC2(GetDecompressedTextureAtMipLevel(0), width, height, rewriteMeProperlyPlease); data = rewriteMeProperlyPlease; break; case VTexFormat.ETC2_EAC: var etc2 = new Etc.EtcDecoder(); var rewriteMeProperlyPlease2 = new byte[data.Length]; // TODO etc2.DecompressETC2A8(GetDecompressedTextureAtMipLevel(0), width, height, rewriteMeProperlyPlease2); data = rewriteMeProperlyPlease2; break; default: throw new NotImplementedException(string.Format("Unhandled image type: {0}", Format)); } // pin the managed array so that the GC doesn't move it // TODO: There's probably a better way of handling this with Span<byte> var gcHandle = GCHandle.Alloc(data.ToArray(), GCHandleType.Pinned); // install the pixels with the color type of the pixel data var bitmap = new SKBitmap(); bitmap.InstallPixels(imageInfo, gcHandle.AddrOfPinnedObject(), imageInfo.RowBytes, (address, context) => { gcHandle.Free(); }, null); return(bitmap); }
public SKBitmap ImageBufferToSKBitmap(IImageBuffer imageBuffer) { if (imageBuffer == null) { return(null); } imageBuffer = imageBuffer.ToU8(); SKBitmap bitmap = null; SKColorSpace colorSpace = null; if (imageBuffer.Format.ColorSpace == ColorSpace.Srgb) { colorSpace = SKColorSpace.CreateSrgb(); } else if (imageBuffer.Format.ColorSpace == ColorSpace.LinearRgb) { colorSpace = SKColorSpace.CreateSrgbLinear(); } try { // for RGBA-images if (imageBuffer.Format.PixelType == PixelType.U8C3) { // convert to 32bpp var src = imageBuffer is I <byte>?((I <byte>)imageBuffer).Data.Buffer : imageBuffer.ToByteArray(); var dst = new byte[imageBuffer.Height * imageBuffer.Width * 4]; int i = 0, j = 0; while (i < dst.Length) { dst[i + 0] = src[j + 0]; dst[i + 1] = src[j + 1]; dst[i + 2] = src[j + 2]; dst[i + 3] = 0xff; i += 4; j += 3; } SKColorType colorType = SKColorType.Rgba8888; switch (imageBuffer.Format.PixelChannels) { case PixelChannels.Rgb: colorType = SKColorType.Rgba8888; break; case PixelChannels.Bgra: colorType = SKColorType.Bgra8888; break; } using (var pinnedImage = new Utilities.PinnedGCHandle(dst)) { var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, colorType, SKAlphaType.Opaque); if (colorSpace != null) { sourceInfo.ColorSpace = colorSpace; } bitmap = new SKBitmap(); Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width * 4); if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer)) { throw new Exception("InstallPixels poperation of Skia bitmap failed."); } } } // for RGBA-images else if (imageBuffer.Format.PixelType == PixelType.U8C4) { // try direct copy using (var pinnedImage = imageBuffer.Pin()) { SKAlphaType alphaType = SKAlphaType.Unknown; SKColorType colorType = SKColorType.Rgba8888; switch (imageBuffer.Format.PixelChannels) { case PixelChannels.Rgbx: alphaType = SKAlphaType.Opaque; colorType = SKColorType.Rgba8888; break; case PixelChannels.Rgba: alphaType = SKAlphaType.Unpremul; colorType = SKColorType.Rgba8888; break; case PixelChannels.Bgrx: alphaType = SKAlphaType.Opaque; colorType = SKColorType.Bgra8888; break; case PixelChannels.Bgra: alphaType = SKAlphaType.Unpremul; colorType = SKColorType.Bgra8888; break; } var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, colorType, alphaType); Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width * 4); if (colorSpace != null) { sourceInfo.ColorSpace = colorSpace; } bitmap = new SKBitmap(); if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer)) { throw new Exception("InstallPixels poperation of Skia bitmap failed."); } } } // for gray-scale else if (imageBuffer.Format.PixelType == PixelType.U8C1) { // try direct copy using (var pinnedImage = imageBuffer.Pin()) { var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, SKColorType.Gray8); Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width); bitmap = new SKBitmap(); if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer)) { throw new Exception("InstallPixels poperation of Skia bitmap failed."); } } } else { throw new Exception("PixelFormat not yet implemented for preview image."); } SKBitmap result = bitmap; bitmap = null; colorSpace = null; return(result); } finally { if (bitmap != null) { bitmap.Dispose(); if (colorSpace != null) { colorSpace.Dispose(); } } } }
public unsafe CefRect Draw(CefPaintEventArgs e) { float ppd = OffscreenGraphics.PixelsPerDip; VirtualDevice device = this.Device; CefRect[] dirtyRects = e.DirtyRects; if (dirtyRects.Length == 0) { return(new CefRect()); } CefRect r = dirtyRects[0]; CefRect invalidRect = new CefRect(r.X, r.Y, r.Width, r.Height); for (int i = 1; i < dirtyRects.Length; i++) { invalidRect.Union(dirtyRects[i]); } if (device != null) { invalidRect.Scale(device.Scale * ppd / device.DevicePixelRatio); } if (e.PaintElementType == CefPaintElementType.Popup) { invalidRect.Offset(_popupBounds.X, _popupBounds.Y); } if (invalidRect.IsNullSize) { return(new CefRect()); } lock (_syncRoot) { int width = e.Width; int height = e.Height; if (device != null) { if (e.PaintElementType == CefPaintElementType.View) { width = (int)(_bounds.Width * device.Scale * ppd); height = (int)(_bounds.Height * device.Scale * ppd); } else if (e.PaintElementType == CefPaintElementType.Popup) { width = (int)(e.Width / device.DevicePixelRatio * device.Scale * ppd); height = (int)(e.Height / device.DevicePixelRatio * device.Scale * ppd); } } PixelBuffer pixelBuffer; if (e.PaintElementType == CefPaintElementType.View) { if (ViewPixels == null || ViewPixels.Width != width || ViewPixels.Height != height) { if (ViewPixels != null) { ViewPixels.Dispose(); } ViewPixels = new PixelBuffer(width, height); } pixelBuffer = ViewPixels; } else if (e.PaintElementType == CefPaintElementType.Popup) { if (PopupPixels == null || PopupPixels.Width != width || PopupPixels.Height != height) { if (PopupPixels != null) { PopupPixels.Dispose(); } PopupPixels = new PixelBuffer(width, height); } pixelBuffer = PopupPixels; } else { return(new CefRect()); } if (e.Width == pixelBuffer.Width && e.Height == pixelBuffer.Height) { long bufferSize = pixelBuffer.Source.ByteCount; Buffer.MemoryCopy(e.Buffer.ToPointer(), pixelBuffer.Source.GetPixels().ToPointer(), bufferSize, bufferSize); } else { using (var canvas = new SKCanvas(pixelBuffer.Source)) using (var paint = new SKPaint()) { canvas.Clear(); paint.FilterQuality = SKFilterQuality.Medium; using (var source = new SKBitmap()) { source.InstallPixels(new SKImageInfo(e.Width, e.Height, SKColorType.Bgra8888, SKAlphaType.Opaque), e.Buffer); canvas.DrawBitmap(source, new SKRect(0, 0, pixelBuffer.Width, pixelBuffer.Height), paint); } canvas.Flush(); } } } invalidRect.Inflate(2, 2); return(invalidRect); }
public SKBitmap GenerateBitmap() { Reader.BaseStream.Position = DataOffset; var width = ActualWidth >> MipmapLevelToExtract; var height = ActualHeight >> MipmapLevelToExtract; var blockWidth = Width >> MipmapLevelToExtract; var blockHeight = Height >> MipmapLevelToExtract; var skiaBitmap = new SKBitmap(width, height, SKColorType.Bgra8888, SKAlphaType.Unpremul); SkipMipmaps(); switch (Format) { case VTexFormat.DXT1: return(TextureDecompressors.UncompressDXT1(skiaBitmap, GetTextureSpan(), blockWidth, blockHeight)); case VTexFormat.DXT5: var yCoCg = false; var normalize = false; var invert = false; var hemiOct = false; if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies)) { var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies]; yCoCg = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image YCoCg Conversion"); normalize = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image NormalizeNormals"); invert = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version LegacySource1InvertNormals"); hemiOct = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Mip HemiOctAnisoRoughness"); } return(TextureDecompressors.UncompressDXT5(skiaBitmap, GetTextureSpan(), blockWidth, blockHeight, yCoCg, normalize, invert, hemiOct)); case VTexFormat.I8: return(TextureDecompressors.ReadI8(skiaBitmap, GetTextureSpan())); case VTexFormat.RGBA8888: return(TextureDecompressors.ReadRGBA8888(skiaBitmap, GetTextureSpan())); case VTexFormat.R16: return(TextureDecompressors.ReadR16(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG1616: return(TextureDecompressors.ReadRG1616(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA16161616: return(TextureDecompressors.ReadRGBA16161616(skiaBitmap, GetTextureSpan())); case VTexFormat.R16F: return(TextureDecompressors.ReadR16F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG1616F: return(TextureDecompressors.ReadRG1616F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA16161616F: return(TextureDecompressors.ReadRGBA16161616F(skiaBitmap, GetTextureSpan())); case VTexFormat.R32F: return(TextureDecompressors.ReadR32F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RG3232F: return(TextureDecompressors.ReadRG3232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGB323232F: return(TextureDecompressors.ReadRGB323232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.RGBA32323232F: return(TextureDecompressors.ReadRGBA32323232F(GetDecompressedBuffer(), Width, Height)); case VTexFormat.BC6H: return(BPTC.BPTCDecoders.UncompressBC6H(GetDecompressedBuffer(), Width, Height)); case VTexFormat.BC7: bool hemiOctRB = false; invert = false; if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies)) { var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies]; hemiOctRB = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Mip HemiOctIsoRoughness_RG_B"); invert = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version LegacySource1InvertNormals"); } return(BPTC.BPTCDecoders.UncompressBC7(GetDecompressedBuffer(), Width, Height, hemiOctRB, invert)); case VTexFormat.ATI2N: normalize = false; if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies)) { var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies]; normalize = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image NormalizeNormals"); } return(TextureDecompressors.UncompressATI2N(skiaBitmap, GetTextureSpan(), Width, Height, normalize)); case VTexFormat.IA88: return(TextureDecompressors.ReadIA88(skiaBitmap, GetTextureSpan())); case VTexFormat.ATI1N: return(TextureDecompressors.UncompressATI1N(skiaBitmap, GetTextureSpan(), Width, Height)); // TODO: Are we sure DXT5 and RGBA8888 are just raw buffers? case VTexFormat.JPEG_DXT5: case VTexFormat.JPEG_RGBA8888: case VTexFormat.PNG_DXT5: case VTexFormat.PNG_RGBA8888: return(ReadBuffer()); case VTexFormat.ETC2: // TODO: Rewrite EtcDecoder to work on skia span directly var etc = new Etc.EtcDecoder(); var data = new byte[skiaBitmap.RowBytes * skiaBitmap.Height]; etc.DecompressETC2(GetDecompressedTextureAtMipLevel(0), width, height, data); var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned); skiaBitmap.InstallPixels(skiaBitmap.Info, gcHandle.AddrOfPinnedObject(), skiaBitmap.RowBytes, (address, context) => { gcHandle.Free(); }, null); break; case VTexFormat.ETC2_EAC: // TODO: Rewrite EtcDecoder to work on skia span directly var etc2 = new Etc.EtcDecoder(); var data2 = new byte[skiaBitmap.RowBytes * skiaBitmap.Height]; etc2.DecompressETC2A8(GetDecompressedTextureAtMipLevel(0), width, height, data2); var gcHandle2 = GCHandle.Alloc(data2, GCHandleType.Pinned); skiaBitmap.InstallPixels(skiaBitmap.Info, gcHandle2.AddrOfPinnedObject(), skiaBitmap.RowBytes, (address, context) => { gcHandle2.Free(); }, null); break; case VTexFormat.BGRA8888: return(TextureDecompressors.ReadBGRA8888(skiaBitmap, GetTextureSpan())); default: throw new NotImplementedException(string.Format("Unhandled image type: {0}", Format)); } return(skiaBitmap); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; if (skiaCanvasWidth == -1) { skiaCanvasWidth = info.Width; skiaCanvasHeight = info.Height; return; //一回目は空打ちなのでreturnする } if (h264DecodedWidth != -1) { float original_height = -1; float original_width = -1; if (h264DecodedHeight != -1) { original_width = h264DecodedWidth; original_height = h264DecodedHeight; } else { original_width = metaData.width; original_height = metaData.height; } if (!isBitDisplayComponetsAdded) { return; } float fit_width = original_width; float fit_height = original_height; float x_ratio = info.Width / (float)original_width; float y_ratio = info.Height / (float)original_height; if (x_ratio < y_ratio) { fit_width *= x_ratio; fit_height *= x_ratio; } else { fit_width *= y_ratio; fit_height *= y_ratio; } //SKRect destRect = new SKRect(info.Width - fit_width, 0, fit_width, fit_height); SKRect destRect = new SKRect(0, 0, fit_width, fit_height); SKRect sourceRect = new SKRect(0, 0, original_width, original_height); byte[] bitmap_data = null; long dataLength = -1; // curUpdateTargetComoonentOrBuf は既に更新中のものになっているはずなので、以下はその前提 if (curUpdateTargetComoonentOrBuf == BITMAP_DISPLAY_COMPONENT_TAG.COMPONENT_1) { bitmap_data = skiaBufStreams[1].ToArray(); dataLength = skiaBufStreams[1].Length; skiaBufStreams[1].Position = 0; } else { bitmap_data = skiaBufStreams[0].ToArray(); dataLength = skiaBufStreams[0].Length; skiaBufStreams[0].Position = 0; } if (dataLength == 0) { return; } byte[] conved_bmp_data = null; if (h264DecodedPixFmt == 21) // yuv420 semi planar (nv12) { conved_bmp_data = Utils.NV12ToRGBA8888(bitmap_data, (int)original_width, (int)original_height); } else if (h264DecodedPixFmt == 19) // yuv420 planar (yv12) { conved_bmp_data = Utils.YV12ToRGBA8888(bitmap_data, (int)original_width, (int)original_height); } GCHandle gcHandle = GCHandle.Alloc(conved_bmp_data, GCHandleType.Pinned); var skinfo = new SKImageInfo((int)original_width, (int)original_height, SKColorType.Rgba8888, SKAlphaType.Opaque); SKBitmap skbitmap = new SKBitmap(); skbitmap.InstallPixels(skinfo, gcHandle.AddrOfPinnedObject(), skinfo.RowBytes, delegate { gcHandle.Free(); }, null); // Display the bitmap canvas.Clear(); canvas.Scale(1, -1, 0, info.Height / 2); canvas.DrawBitmap(skbitmap, sourceRect, destRect); if (input != null) { input.renderedAreaWidth = (int)destRect.Width; input.renderedAreaHeight = (int)destRect.Height; int[] xy_arr; if ((xy_arr = input.getCursorInternalCursorPos()) != null) { Console.WriteLine("Draw dummy cursor!"); var paint = new SKPaint { Color = new SKColor(255, 0, 0), Style = SKPaintStyle.Fill }; canvas.DrawCircle(xy_arr[0], xy_arr[1], 10.0f, paint); } } Console.WriteLine("double_image: canvas size =" + info.Width.ToString() + "x" + info.Height.ToString() + " scaled image size =" + fit_width.ToString() + "x" + fit_height.ToString()); } }
public SKBitmap GenerateBitmap() { Reader.BaseStream.Position = DataOffset; var width = NonPow2Width > 0 ? NonPow2Width : Width; var height = NonPow2Height > 0 ? NonPow2Height : Height; var imageInfo = new SKImageInfo(width, height, SKColorType.Bgra8888, SKAlphaType.Unpremul); Span <byte> data = new byte[imageInfo.RowBytes * imageInfo.Height]; switch (Format) { case VTexFormat.DXT1: SkipMipmaps(8); TextureDecompressors.UncompressDXT1(imageInfo, Reader, data, Width, Height); break; case VTexFormat.DXT5: var yCoCg = false; var normalize = false; var invert = false; if (Resource.EditInfo.Structs.ContainsKey(ResourceEditInfo.REDIStruct.SpecialDependencies)) { var specialDeps = (SpecialDependencies)Resource.EditInfo.Structs[ResourceEditInfo.REDIStruct.SpecialDependencies]; yCoCg = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image YCoCg Conversion"); normalize = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version Image NormalizeNormals"); invert = specialDeps.List.Any(dependancy => dependancy.CompilerIdentifier == "CompileTexture" && dependancy.String == "Texture Compiler Version LegacySource1InvertNormals"); } SkipMipmaps(16); TextureDecompressors.UncompressDXT5(imageInfo, Reader, data, Width, Height, yCoCg, normalize, invert); break; case VTexFormat.I8: SkipMipmaps(1); return(TextureDecompressors.ReadI8(Reader, Width, Height)); case VTexFormat.RGBA8888: SkipMipmaps(4); return(TextureDecompressors.ReadRGBA8888(Reader, Width, Height)); case VTexFormat.R16: SkipMipmaps(2); return(TextureDecompressors.ReadR16(Reader, Width, Height)); case VTexFormat.RG1616: SkipMipmaps(4); return(TextureDecompressors.ReadRG1616(Reader, Width, Height)); case VTexFormat.RGBA16161616: SkipMipmaps(8); TextureDecompressors.ReadRGBA16161616(imageInfo, Reader, data); break; case VTexFormat.R16F: SkipMipmaps(2); return(TextureDecompressors.ReadR16F(Reader, Width, Height)); case VTexFormat.RG1616F: SkipMipmaps(4); return(TextureDecompressors.ReadRG1616F(Reader, Width, Height)); case VTexFormat.RGBA16161616F: SkipMipmaps(8); TextureDecompressors.ReadRGBA16161616F(imageInfo, Reader, data); break; case VTexFormat.R32F: SkipMipmaps(4); return(TextureDecompressors.ReadR32F(Reader, Width, Height)); case VTexFormat.RG3232F: SkipMipmaps(8); return(TextureDecompressors.ReadRG3232F(Reader, Width, Height)); case VTexFormat.RGB323232F: SkipMipmaps(12); return(TextureDecompressors.ReadRGB323232F(Reader, Width, Height)); case VTexFormat.RGBA32323232F: SkipMipmaps(16); return(TextureDecompressors.ReadRGBA32323232F(Reader, Width, Height)); case VTexFormat.IA88: SkipMipmaps(2); return(TextureDecompressors.ReadIA88(Reader, Width, Height)); case VTexFormat.JPG: case VTexFormat.PNG2: case VTexFormat.PNG: return(ReadBuffer()); default: throw new NotImplementedException(string.Format("Unhandled image type: {0}", Format)); } // pin the managed array so that the GC doesn't move it // TODO: There's probably a better way of handling this with Span<byte> var gcHandle = GCHandle.Alloc(data.ToArray(), GCHandleType.Pinned); // install the pixels with the color type of the pixel data var bitmap = new SKBitmap(); bitmap.InstallPixels(imageInfo, gcHandle.AddrOfPinnedObject(), imageInfo.RowBytes, null, delegate { gcHandle.Free(); }, null); return(bitmap); }
private unsafe void DecodeFrame(IntPtr address, int w, int h) { if (input == null) { width = w; height = h; cDegrees = cameraController.mSensorOrientation; imageData = new int[width * height]; imageGCHandle = GCHandle.Alloc(imageData, GCHandleType.Pinned); imageIntPtr = imageGCHandle.AddrOfPinnedObject(); input = new SKBitmap(new SKImageInfo(width, height, SKColorType.Rgba8888, SKAlphaType.Premul)); } input.InstallPixels(input.Info, address); if (inputCropped == null) { inputCropped = new SKBitmap(new SKImageInfo(width, width, SKColorType.Rgba8888, SKAlphaType.Premul)); } CropInputBitmap(input); if (canAnalyze) { Task.Factory.StartNew(() => { canAnalyze = false; stopwatch.Restart(); inputCropped.ScalePixels(inputScaled_PlateAndMoto, SKFilterQuality.None); inputCropped.ScalePixels(inputScaled_MotoModel, SKFilterQuality.None); stopwatch.Stop(); MainActivity.PlateAndMotoStats.ResizeAndRotateElapsedMs = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); colors_PlateAndMoto = inputScaled_PlateAndMoto.GetPixels(); colors_MotoModel = inputScaled_MotoModel.GetPixels(); tfService_Plate?.Recognize(colors_PlateAndMoto, colorCount_PlateAndMoto); //tfService_Moto?.Recognize(colors_PlateAndMoto, colorCount_PlateAndMoto); stopwatch.Stop(); MainActivity.PlateAndMotoStats.InterpreterElapsedMs = stopwatch.ElapsedMilliseconds; stopwatch.Restart(); tfService_MotoModel?.Recognize(colors_MotoModel, colorCount_MotoModel); stopwatch.Stop(); MainActivity.MotoModelStats.InterpreterElapsedMs = stopwatch.ElapsedMilliseconds; //canAnalyze = true; //MainActivity.context.RunOnUiThread(() => //{ // MainActivity.ReloadCanvas(); //}); }).ContinueWith((t) => { if (t.Exception != null) { Crashes.TrackError(t.Exception); } canAnalyze = true; MainActivity.context.RunOnUiThread(() => { MainActivity.ReloadCanvas(); }); }); } }