예제 #1
0
 public static bool FromGif(string srcFile, string outFile, Size size)
 {
     using (var sKCodec = SKCodec.Create(srcFile))
     {
         using (var bitmap = new SKBitmap(sKCodec.Info))
         {
             if (bitmap.Height > bitmap.Width)
             {
                 size.Width = bitmap.Width * size.Height / bitmap.Height;
             }
             else
             {
                 size.Height = bitmap.Height * size.Width / bitmap.Width;
             }
             sKCodec.GetPixels(sKCodec.Info, bitmap.GetPixels(), new SKCodecOptions(0));
             using (var newBitmap = new SKBitmap(new SKImageInfo(size.Width, size.Height)))
             {
                 bitmap.ScalePixels(newBitmap, SKFilterQuality.Medium);
                 using (var image = SKImage.FromBitmap(newBitmap))
                 {
                     using (var output = File.OpenWrite(outFile))
                     {
                         image.Encode(SKEncodedImageFormat.Jpeg, 100)
                         .SaveTo(output);
                         return(true);
                     }
                 }
             }
         }
     }
 }
예제 #2
0
        public void CanScalePixels()
        {
            var srcInfo = new SKImageInfo(200, 200);
            var dstInfo = new SKImageInfo(100, 100);

            var srcBmp = new SKBitmap(srcInfo);
            var dstBmp = new SKBitmap(dstInfo);

            using (var canvas = new SKCanvas(srcBmp))
                using (var paint = new SKPaint {
                    Color = SKColors.Green
                })
                {
                    canvas.Clear(SKColors.Blue);
                    canvas.DrawRect(new SKRect(0, 0, 100, 200), paint);
                }

            Assert.Equal(SKColors.Green, srcBmp.GetPixel(75, 75));
            Assert.Equal(SKColors.Blue, srcBmp.GetPixel(175, 175));

            Assert.True(srcBmp.ScalePixels(dstBmp, SKFilterQuality.High));

            Assert.Equal(SKColors.Green, dstBmp.GetPixel(25, 25));
            Assert.Equal(SKColors.Blue, dstBmp.GetPixel(75, 75));
        }
        private SKBitmap Scale(SKBitmap input, int width, int height)
        {
            var info   = new SKImageInfo(width, height);
            var newImg = SKImage.Create(info);

            input.ScalePixels(newImg.PeekPixels(), SKFilterQuality.Medium);
            return(SKBitmap.FromImage(newImg));
        }
        public static void mergeTiles(string folderPath)
        {
            if (folderPath.Last() == '/' || folderPath.Last() == '\\')
            {
                folderPath = folderPath.Remove(folderPath.Length - 1);
            }

            Dictionary <string, SKImage> images = new Dictionary <string, SKImage>();
            int maxNumOfLevels = 3;

            for (int level = maxNumOfLevels; level > 0; --level)
            {
                int numOfTiles   = Convert.ToInt32(Math.Pow(4, level - 1));
                int tilesToASide = Convert.ToInt32(Math.Sqrt(numOfTiles));
                for (int globaly = 0; globaly < tilesToASide; ++globaly)
                {
                    for (int globalx = 0; globalx < tilesToASide; ++globalx)
                    {
                        var tempSurface = SKSurface.Create(new SKImageInfo(512, 512));
                        var canvas      = tempSurface.Canvas;
                        canvas.Clear(SKColors.Transparent);
                        for (int tiley = 0; tiley < 2; ++tiley)
                        {
                            for (int tilex = 0; tilex < 2; ++tilex)
                            {
                                int    imgx     = (globalx * 2 + tilex);
                                int    imgy     = (globaly * 2 + tiley);
                                string tilePath = $"{folderPath}/aqlatestL{level}T{(globalx * 2 + tilex).ToString("D2")}{(globaly * 2 + tiley).ToString("D2")}.png";
                                string tileKey  = $"L{level}T{(globalx * 2 + tilex).ToString("D2")}{(globaly * 2 + tiley).ToString("D2")}";
                                if (images.ContainsKey(tileKey))
                                {
                                    SKBitmap tile = SKBitmap.FromImage(images[tileKey]);
                                    canvas.DrawBitmap(tile, SKRect.Create(tilex * 256, tiley * 256, tile.Width, tile.Height));
                                }
                                else if (File.Exists(tilePath))
                                {
                                    SKBitmap tile = SKBitmap.Decode(File.OpenRead(tilePath));
                                    canvas.DrawBitmap(tile, SKRect.Create(tilex * 256, tiley * 256, tile.Width, tile.Height));
                                }
                            }
                        }
                        SKBitmap bigTile    = SKBitmap.FromImage(tempSurface.Snapshot());
                        SKBitmap littleTile = SKBitmap.FromImage(SKImage.Create(new SKImageInfo(256, 256)));
                        bigTile.ScalePixels(littleTile, SKFilterQuality.High);
                        SKImage outTile = SKImage.FromBitmap(littleTile);
                        images.Add($"L{level - 1}T{globalx.ToString("D2")}{globaly.ToString("D2")}", outTile);
                    }
                }
            }

            foreach (KeyValuePair <string, SKImage> file in images)
            {
                var data   = file.Value.Encode();
                var stream = File.OpenWrite($"{folderPath}/aqlatest{file.Key}.png");
                data.SaveTo(stream);
            }
        }
예제 #5
0
        private async Task RezPickedBitmap()
        {
            if (_userPickedBitmap == null)
            {
                return;
            }
            var rez = 100 + RezSlider.Value * 200;

            _applyDitherBitmap = new SKBitmap((int)rez, (int)(rez * (_userPickedBitmap.Height / (double)_userPickedBitmap.Width)));
            _userPickedBitmap.ScalePixels(_applyDitherBitmap, SKFilterQuality.None);
        }
예제 #6
0
        /// <summary>
        /// Resize image to a specific size.
        /// </summary>
        /// <param name="width">Width.</param>
        /// <param name="height">Height.</param>
        /// <returns>New resized image.</returns>
        public IImage ResizeTo(int width, int height)
        {
            SKBitmap newBitmap = new SKBitmap(width, height);

            if (!bitmap.ScalePixels(newBitmap, SKFilterQuality.High))
            {
                newBitmap.Dispose();
                throw new ImageOperationException("SKBitmap.ScalePixels");
            }

            return(new Image(newBitmap));
        }
예제 #7
0
        /// <summary>
        /// Pixelates a given image area defined by extractRect of the original image and draws it to the canvas.
        /// </summary>
        /// <param name="canvas"></param>
        /// <param name="extractRect"></param>
        /// <param name="original"></param>
        /// <param name="pixelSizeFunction"></param>
        private static void Pixelate(SKCanvas canvas, SKRectI extractRect, SKBitmap original,
                                     Func <int, int, int, int, int> pixelSizeFunction)
        {
            var pixelSize =
                pixelSizeFunction.Invoke(original.Width, original.Height, extractRect.Width, extractRect.Height);

            var downscaled = new SKBitmap(extractRect.Width / pixelSize, extractRect.Height / pixelSize);
            var upscaled   = new SKBitmap(extractRect.Width, extractRect.Height);
            var sub        = new SKBitmap();

            original.ExtractSubset(sub, extractRect);
            sub.ScalePixels(downscaled, SKFilterQuality.None);
            downscaled.ScalePixels(upscaled, SKFilterQuality.None);
            canvas.DrawBitmap(upscaled, extractRect);
        }
예제 #8
0
        internal static SKBitmap GetBlurBitmap(SKBitmap bitmap, SKRect rect)
        {
            SKBitmap outBitmap = new SKBitmap((int)rect.Width, (int)rect.Height);

            using (SKBitmap tempBitmap = new SKBitmap(CalcBackgraundBitmapsize(bitmap.Width), CalcBackgraundBitmapsize(bitmap.Height)))
                using (SKCanvas canvas = new SKCanvas(outBitmap))
                    using (SKPaint paint = new SKPaint())
                    {
                        bitmap.ScalePixels(tempBitmap, SKFilterQuality.Low);
                        paint.IsAntialias = true;
                        float blur = 0.08f * Math.Max(rect.Width, rect.Height);
                        blur = blur < 100 ? blur : 100;
                        paint.ImageFilter = SKImageFilter.CreateBlur(blur, blur);
                        canvas.Clear();
                        canvas.DrawBitmap(tempBitmap, rect, paint);
                    }
            GC.Collect(0);
            return(outBitmap);
        }
예제 #9
0
        /// <summary>
        /// <br>Encode the Input file Image, binarize it and save to an output file image</br>
        /// <br>Default image format: Png</br>
        /// </summary>
        /// <param name="inputFile">Input image path</param>
        /// <param name="outputFile">Output image path</param>
        /// <param name="encodingFormat">One of following formats is supported: Bmp, Gif, Ico, Jpeg, Png, Wbmp, Webp, Pkm, Ktx, Astc, Dng, Heif </param>
        public void EncodeAndSaveAsImage(string inputFile, string outputFile, string encodingFormat = "Png")
        {
            //
            // 1. Initiate the parameters
            this.binarizerParams.InputImagePath  = inputFile;
            this.binarizerParams.OutputImagePath = outputFile;
            double[,,] binarizedImage            = GetPixels();

            //
            // 2. Reading the inputFile image to type SKBitmap
            SKBitmap inputBitmap  = SKBitmap.Decode(inputFile);
            SKBitmap outputBitmap = new SKBitmap(binarizerParams.ImageWidth, binarizerParams.ImageHeight);

            inputBitmap.ScalePixels(outputBitmap, SKFilterQuality.High);
            for (int y = 0; y < outputBitmap.Height; y++)
            {
                for (int x = 0; x < outputBitmap.Width; x++)
                {
                    int b = (int)binarizedImage[y, x, 0];
                    outputBitmap.SetPixel(x, y, new SKColor((byte)(255 * b), (byte)(255 * b), (byte)(255 * b)));
                }
            }

            //
            // 3. Reading a Picture file in pixels
            using (var image = SKImage.FromBitmap(outputBitmap))
            {
                SKEncodedImageFormat frm = (SKEncodedImageFormat)Enum.Parse(typeof(SKEncodedImageFormat), encodingFormat);

                using (var data = image.Encode(frm, 80))
                {
                    // save the data to a stream
                    using (var stream = File.OpenWrite($"{outputFile}"))
                    {
                        data.SaveTo(stream);
                    }
                }
            }
        }
예제 #10
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();
        }
예제 #11
0
        private async Task DrawScaledUpImage()
        {
            if (_applyDitherBitmap == null)
            {
                return;
            }

            if (SkiaView.CanvasSize.Width > 0)
            {
                int newCanvasWidth  = (int)SkiaView.CanvasSize.Width;
                int newCanvasHeight = (int)(SkiaView.CanvasSize.Width * (_applyDitherBitmap.Height / (double)_applyDitherBitmap.Width));
                if ((int)SkiaView.CanvasSize.Width > (int)SkiaView.CanvasSize.Height)
                {
                    newCanvasWidth  = (int)(SkiaView.CanvasSize.Height * (_applyDitherBitmap.Width / (double)_applyDitherBitmap.Height));
                    newCanvasHeight = (int)SkiaView.CanvasSize.Height;
                }

                _drawBitmap = new SKBitmap(newCanvasWidth, newCanvasHeight);
            }

            _applyDitherBitmap.ScalePixels(_drawBitmap, SKFilterQuality.None);

            SkiaView.InvalidateSurface();
        }
예제 #12
0
        public static Dictionary <string, SKBitmap> GetEmotes(List <Comment> comments, string cacheFolder, Emotes embededEmotes = null, bool deepSearch = false)
        {
            Dictionary <string, SKBitmap> returnDictionary = new Dictionary <string, SKBitmap>();
            List <string> alreadyAdded = new List <string>();
            List <string> failedEmotes = new List <string>();

            string emoteFolder = Path.Combine(cacheFolder, "emotes");

            if (!Directory.Exists(emoteFolder))
            {
                Directory.CreateDirectory(emoteFolder);
            }

            if (embededEmotes != null)
            {
                foreach (FirstPartyEmoteData emoteData in embededEmotes.firstParty)
                {
                    try
                    {
                        if (!returnDictionary.ContainsKey(emoteData.id))
                        {
                            returnDictionary.Add(emoteData.id, SKBitmap.Decode(emoteData.data));
                            alreadyAdded.Add(emoteData.id);
                        }
                    }
                    catch { }
                }
            }

            using (WebClient client = new WebClient())
            {
                foreach (var comment in comments)
                {
                    if (comment.message.fragments == null)
                    {
                        continue;
                    }

                    foreach (var fragment in comment.message.fragments)
                    {
                        if (fragment.emoticon != null)
                        {
                            string id = fragment.emoticon.emoticon_id;
                            if (!alreadyAdded.Contains(id) && !failedEmotes.Contains(id))
                            {
                                try
                                {
                                    string filePath = Path.Combine(emoteFolder, id + "_1x.png");

                                    if (File.Exists(filePath))
                                    {
                                        SKBitmap emoteImage = SKBitmap.Decode(filePath);
                                        if (emoteImage == null)
                                        {
                                            try
                                            {
                                                File.Delete(filePath);
                                            }
                                            catch { }
                                        }
                                        else
                                        {
                                            returnDictionary.Add(id, emoteImage);
                                            alreadyAdded.Add(id);
                                        }
                                    }

                                    if (!alreadyAdded.Contains(id))
                                    {
                                        byte[] bytes = client.DownloadData(String.Format("https://static-cdn.jtvnw.net/emoticons/v1/{0}/1.0", id));
                                        alreadyAdded.Add(id);
                                        MemoryStream ms         = new MemoryStream(bytes);
                                        SKBitmap     emoteImage = SKBitmap.Decode(ms);
                                        returnDictionary.Add(id, emoteImage);
                                        File.WriteAllBytes(filePath, bytes);
                                    }
                                }
                                catch (WebException)
                                {
                                    string emoteName  = fragment.text;
                                    bool   foundEmote = false;

                                    if (deepSearch)
                                    {
                                        //lets try waybackmachine, very slow though :(
                                        try
                                        {
                                            for (int i = 1; i <= 3; i++)
                                            {
                                                JObject response = JObject.Parse(client.DownloadString($"https://archive.org/wayback/available?url=https://static-cdn.jtvnw.net/emoticons/v1/{id}/{i}.0/"));
                                                if (response["archived_snapshots"]["closest"] != null && response["archived_snapshots"]["closest"]["available"].ToObject <bool>() == true)
                                                {
                                                    string       filePath         = Path.Combine(emoteFolder, id + "_1x.png");
                                                    byte[]       bytes            = client.DownloadData(response["archived_snapshots"]["closest"]["url"].ToString().Replace("/https://static-cdn.jtvnw.net", "if_/https://static-cdn.jtvnw.net"));
                                                    MemoryStream ms               = new MemoryStream(bytes);
                                                    SKBitmap     emoteImage       = SKBitmap.Decode(ms);
                                                    SKBitmap     emoteImageScaled = new SKBitmap(28, 28);
                                                    emoteImage.ScalePixels(emoteImageScaled, SKFilterQuality.High);
                                                    alreadyAdded.Add(id);
                                                    returnDictionary.Add(id, emoteImageScaled);
                                                    emoteImage.Dispose();
                                                    emoteImageScaled.Encode(SKEncodedImageFormat.Png, 100).SaveTo(new FileStream(filePath, FileMode.Create));
                                                    foundEmote = true;
                                                    break;
                                                }
                                            }
                                        }
                                        catch { }


                                        if (foundEmote)
                                        {
                                            continue;
                                        }
                                        else
                                        {
                                            //sometimes emote still exists but id is different, I use twitch metrics because I can't find an api to find an emote by name
                                            try
                                            {
                                                HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.twitchmetrics.net/e/" + emoteName);
                                                request.AllowAutoRedirect = false;
                                                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                                                string          redirUrl = response.Headers["Location"];
                                                response.Close();
                                                string newId    = redirUrl.Split('/').Last().Split('-').First();
                                                byte[] bytes    = client.DownloadData(String.Format("https://static-cdn.jtvnw.net/emoticons/v1/{0}/1.0", newId));
                                                string filePath = Path.Combine(emoteFolder, id + "_1x.png");
                                                File.WriteAllBytes(filePath, bytes);
                                                alreadyAdded.Add(id);
                                                MemoryStream ms         = new MemoryStream(bytes);
                                                SKBitmap     emoteImage = SKBitmap.Decode(ms);
                                                returnDictionary.Add(id, emoteImage);
                                                foundEmote = true;
                                            }
                                            catch
                                            {
                                            }
                                        }
                                    }
                                    if (!foundEmote)
                                    {
                                        failedEmotes.Add(id);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(returnDictionary.Where(x => x.Value != null).ToDictionary(z => z.Key, z => z.Value));
        }
예제 #13
0
        static public MemoryStream Encode(FileStream surPicFile, FileStream insPicFile, string info, int compress)
        {
            if (compress == 0 || compress >= 8)
            {
                return(null);
            }

            byte[] lsbMask   = { 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F };
            char[] signature = "/By:f_Endman".ToCharArray();

            long insPicLength = insPicFile.Length;

            SKBitmap surPic = SKBitmap.Decode(surPicFile);

            //得到隐写里图所需的表图的尺寸,并缩放表图
            long   byteForLSB        = insPicLength * 8 / compress;                                           //隐写所有里数据所需的表图字节数
            long   currentSurPicByte = surPic.Width * surPic.Height * 3;                                      //表图现有的可用于LSB隐写的字节数
            double zoom = (double)byteForLSB / (double)currentSurPicByte * ((compress >= 6) ? 1.05d : 1.01d); //表图需要缩放的倍数(留出1%-5%余量)

            /* 问题可转化为两矩形已知前后面积比例zoom,前者宽度高度a1,b1和a1/b1,并且两矩形长宽比相同即a1/b1=a2/b2;求后者矩形的长a2与宽b2 *
             * ∵a1/b1=a2/b2   ∴a2=a1/b1*b2   又∵a1*b1*zoom=a2*b2   ∴联立可解得b2=b1*根号zoom   ∴a2=a1*根号zoom                       */
            double   squareRootZoom = Math.Sqrt(zoom);
            SKBitmap tankPic        = new SKBitmap((int)(surPic.Width * squareRootZoom), (int)(surPic.Height * squareRootZoom), SKColorType.Bgra8888, SKAlphaType.Premul);

            surPic.ScalePixels(tankPic, SKFilterQuality.High);

            //为表图添加水印
            SKPaint paint = new SKPaint
            {
                Color       = SKColors.Black,
                TextSize    = 24,
                IsAntialias = true,                                                                                                               //抗锯齿
                Typeface    = SKTypeface.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("WarFactory.Resources.simhei.ttf")) //使用内嵌的字体
            };
            SKRect textSize = new SKRect();

            paint.MeasureText(info, ref textSize);  //得到文字的尺寸
            int textWidth = (int)(textSize.Size.Width + 2);

            if (textWidth > tankPic.Width)
            {
                textWidth = tankPic.Width;
            }
            SKBitmap infoPic = new SKBitmap(textWidth, 30); //创建水印
            SKCanvas canvas  = new SKCanvas(infoPic);

            canvas.DrawColor(SKColors.White);
            canvas.DrawText(info, 0, (30 - textSize.Size.Height) / 2 - textSize.Top, paint);
            byte alpha = 0xCF;                       //水印不透明度

            for (int i = 0; i < infoPic.Height; i++) //混色
            {
                for (int j = 0; j < infoPic.Width; j++)
                {
                    SKColor infoColor = infoPic.GetPixel(j, i);
                    SKColor surColor  = tankPic.GetPixel(j, i);
                    byte    red       = (byte)((infoColor.Red * alpha + surColor.Red * (0xFF - alpha)) / 0xFF);
                    byte    green     = (byte)((infoColor.Green * alpha + surColor.Green * (0xFF - alpha)) / 0xFF);
                    byte    blue      = (byte)((infoColor.Blue * alpha + surColor.Blue * (0xFF - alpha)) / 0xFF);
                    tankPic.SetPixel(j, i, new SKColor(red, green, blue));
                }
            }

            //写入里数据文件头(根据网页源码以及WinHex亲测推测)

            /* 结构如下:
             * 里数据大小(字符串格式)
             * '\1'
             * 里文件名称
             * '\1'
             * 里文件格式(特定字符串):目前我见过的原作者写的有"image/jpeg"和"image/png"和"image/png"三种,这个应该是关系到网页版解码后显示(我本业是嵌入式,让我完全弄明白这玩意就是难为我QWQ)
             * '\0'
             */
            List <byte> insPicByteList = new List <byte>();

            char[] insPicLengthStr = insPicLength.ToString().ToCharArray();
            for (int i = 0; i < insPicLengthStr.Length; i++)
            {
                insPicByteList.Add((byte)insPicLengthStr[i]);
            }

            insPicByteList.Add(0x01);

            char[] insPicLengthFileName = insPicFile.Name.Substring(insPicFile.Name.LastIndexOf("/") + 1).ToCharArray(); //获取包含扩展名的文件名
            for (int i = 0; i < insPicLengthFileName.Length; i++)
            {
                insPicByteList.Add((byte)insPicLengthFileName[i]);
            }

            insPicByteList.Add(0x01);

            char[] insMime;
            insMime = MimeUtility.GetMimeMapping(insPicFile.Name).ToCharArray();

            for (int i = 0; i < insMime.Length; i++)
            {
                insPicByteList.Add((byte)insMime[i]);
            }

            insPicByteList.Add(0x00);

            //读取里数据
            byte[] insPicByte = new byte[insPicFile.Length];
            insPicFile.Read(insPicByte, 0, (int)insPicFile.Length);
            insPicFile.Seek(0, SeekOrigin.Begin);
            insPicByteList.AddRange(new List <byte>(insPicByte));

            //BGRA转RGB
            SKColor[] tankColorArray = tankPic.Pixels;
            byte[]    tankByteArray  = new byte[tankColorArray.Length * 3];
            for (int i = 0; i < tankColorArray.Length; i++)
            {
                tankByteArray[i * 3 + 0] = (tankColorArray[i].Red);
                tankByteArray[i * 3 + 1] = (tankColorArray[i].Green);
                tankByteArray[i * 3 + 2] = (tankColorArray[i].Blue);
            }

            //前三个字节为数据标识保留(根据网页源码推测)

            /* 原图数据前三个字节推测如下:
             *  Byte[0]:低3位固定为0x0
             *  Byte[1]:低3位固定为0x3
             *  Byte[2]:低3位数据为LSB隐写的位数,对应网页版的压缩度    1 <= (Byte[2] & 0x7) <= 4
             */
            tankByteArray[0] &= 0xF8;
            tankByteArray[0] |= 0x00;
            tankByteArray[1] &= 0xF8;
            tankByteArray[1] |= 0x03;
            tankByteArray[2] &= 0xF8;
            tankByteArray[2] |= (byte)(compress & 0x7);

            //---LSB隐写,具体细节很繁琐,用到了一堆位运算---//
            int   Count = 0, snCount = 0;
            Int32 FIFO      = 0;                               //先进先出,用于缓存LSB
            int   FifoCount = 0;                               //FIFO中剩余的要写入的LSB的数量

            byte[] insPicByteArray = insPicByteList.ToArray(); //直接用List速度比较慢
            insPicByteList.Clear();
            for (int i = 3; i < tankByteArray.Length; i++)
            {
                if (FifoCount < compress)   //FIFO不够写了就读一个字节
                {
                    //无影坦克的LSB是大端的,所以从"左"取数据,即先取高位
                    //如果里数据已经全部写入,就填充签名字符串
                    FIFO      |= (Int32)(((Count < insPicByteArray.Length) ? insPicByteArray[Count++] : (byte)signature[snCount++ % signature.Length]) << (/* 32 - 8 */ 24 - FifoCount));
                    FifoCount += 8;
                }
                tankByteArray[i] &= (byte)~lsbMask[compress - 1];   //清除低n位
                //无影坦克的LSB是大端的,所以从"左"取数据,即先取高位
                tankByteArray[i] |= (byte)((FIFO >> (32 - compress)) & lsbMask[compress - 1]);
                FIFO            <<= compress;
                FifoCount        -= compress;
            }

            for (int i = 0; i < tankColorArray.Length; i++)
            {
                tankColorArray[i] = new SKColor(tankByteArray[i * 3 + 0], tankByteArray[i * 3 + 1], tankByteArray[i * 3 + 2]);
            }
            tankPic.Pixels = tankColorArray;

            byte[] tankPicArray = tankPic.Encode(SKEncodedImageFormat.Png, 100).ToArray();

            surPicFile.Close();
            surPicFile.Dispose();
            insPicFile.Close();
            insPicFile.Dispose();

            return(new MemoryStream(tankPicArray));
        }
예제 #14
0
        /// <summary>
        /// Load an image from the phone
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private async void LoadImage(object sender, EventArgs args)
        {
            IPhotoLibrary photoLibrary = DependencyService.Get <IPhotoLibrary>();

            using (Stream stream = await photoLibrary.PickPhotoAsync())
            {
                if (stream != null)
                {
                    SKBitmap loaded = SKBitmap.Decode(stream);
                    if (loaded != null)
                    {
                        if (animation)
                        {
                            StopAccelerometer();
                        }


                        //Set the image dimensions
                        width  = (int)imgGenerated.CanvasSize.ToFormsSize().Width;
                        height = (int)imgGenerated.CanvasSize.ToFormsSize().Height;

                        int oldSize = width;
                        if (width > height)
                        {
                            oldSize = height;
                        }

                        int size = oldSize;
                        for (int i = 1; i < oldSize; i <<= 1)
                        {
                            size = i;
                        }

                        width  = size;
                        height = size;

                        generator.SetDimensions(width, height);


                        // Resize the loaded image
                        //source: https://stackoverflow.com/questions/48422724/fastest-way-to-scale-an-skimage-skiasharp
                        SKImageInfo info = new SKImageInfo(width, height, SKColorType.Rgba8888);

                        SKImage output = SKImage.Create(info);

                        loaded.ScalePixels(output.PeekPixels(), SKFilterQuality.None);

                        imgBitmap = SKBitmap.FromImage(output);

                        skRect = new SKRect(0, 0, oldSize, oldSize);

                        generator.Load(imgBitmap);
                        imgGenerated.InvalidateSurface();

                        if (animation)
                        {
                            StartAccelerometer();
                        }
                    }
                }
            }
        }