Пример #1
0
        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);
                }
            }
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }
Пример #6
0
        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();
                    }
                }
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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());
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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();
                    });
                });
            }
        }