Пример #1
0
        public void TakeScreenshot(string filePath)
        {
            using Stream memStream         = File.Open(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
            using SKManagedWStream wstream = new(memStream);

            _bitmap?.Encode(wstream, SKEncodedImageFormat.Png, 100);
        }
Пример #2
0
        /// <summary>
        /// Take a path provided by a user, draw it as a maptile. Potentially useful for exercise trackers. Resulting file must not be saved to the server as that would be user tracking.
        /// </summary>
        /// <param name="pointListAsString">a string of points separate by , and | </param>
        /// <returns>the png file with the path drawn over the mapdata in the area.</returns>
        public byte[] DrawUserPath(string pointListAsString)
        {
            //String is formatted as Lat,Lon~Lat,Lon~ repeating. Characters chosen to not be percent-encoded if submitted as part of the URL.
            //first, convert this to a list of latlon points
            string[]          pointToConvert = pointListAsString.Split("|");
            List <Coordinate> coords         = pointToConvert.Select(p => new Coordinate(double.Parse(p.Split(',')[0]), double.Parse(p.Split(',')[1]))).ToList();

            var     mapBuffer = resolutionCell8 / 2; //Leave some area around the edges of where they went.
            GeoArea mapToDraw = new GeoArea(coords.Min(c => c.Y) - mapBuffer, coords.Min(c => c.X) - mapBuffer, coords.Max(c => c.Y) + mapBuffer, coords.Max(c => c.X) + mapBuffer);

            ImageStats info = new ImageStats(mapToDraw, 1024, 1024);

            LineString line         = new LineString(coords.ToArray());
            var        drawableLine = PolygonToSKPoints(line, mapToDraw, info.degreesPerPixelX, info.degreesPerPixelY);

            //Now, draw that path on the map.
            var places    = GetPlaces(mapToDraw); //, null, false, false, degreesPerPixelX * 4 ///TODO: restore item filtering
            var baseImage = DrawAreaAtSize(info, places);

            SKBitmap sKBitmap = SKBitmap.Decode(baseImage);
            SKCanvas canvas   = new SKCanvas(sKBitmap);
            SKPaint  paint    = new SKPaint();

            paint.Style       = SKPaintStyle.Stroke;
            paint.StrokeWidth = 4;                    //Larger than normal lines at any zoom level.
            paint.Color       = new SKColor(0, 0, 0); //Pure black, for maximum visibility.
            for (var x = 0; x < drawableLine.Length - 1; x++)
            {
                canvas.DrawLine(drawableLine[x], drawableLine[x + 1], paint);
            }

            var ms   = new MemoryStream();
            var skms = new SKManagedWStream(ms);

            sKBitmap.Encode(skms, SKEncodedImageFormat.Png, 100);
            var results = ms.ToArray();

            skms.Dispose(); ms.Close(); ms.Dispose();
            return(results);
        }
Пример #3
0
        private Result GetImagePart(Mnemonic expression, IRuntime runtime)
        {
            if (
                runtime.GetVariable("arrayOfBinaryData").Get(runtime) is String arrayImage &&
                runtime.GetVariable("left").Get(runtime) is Number a &&
                runtime.GetVariable("top").Get(runtime) is Number b &&
                runtime.GetVariable("right").Get(runtime) is Number c &&
                runtime.GetVariable("bottom").Get(runtime) is Number d
                )
            {
                var binaryData =
                    Convert.FromBase64String(arrayImage.Value);

                //arrayImage
                //.Select(e => e as Number)
                //.Select(n => n.ValueAsByte)
                //.ToArray();
                var resourceBitmap = SKBitmap.Decode(binaryData);

                var bmp = new SKBitmap();
                resourceBitmap.ExtractSubset(bmp,
                                             new SKRectI(a.ValueAsInt, b.ValueAsInt, c.ValueAsInt, d.ValueAsInt));

                SKDynamicMemoryWStream ms = new SKDynamicMemoryWStream();
                var data = bmp.Encode(SKEncodedImageFormat.Png, 100);

                var subimage = Convert.ToBase64String(data.ToArray());
                //LoplaList loplaList = new LoplaList();

                //foreach(var dbyte in data.ToArray())
                //{
                //    loplaList.Add(new Number(dbyte));
                //}

                //return new Result(loplaList);
                return(new Result(new String(subimage)));
            }

            return(new Result());
        }
        protected static Bitmap?GetBitmap(ImageSouce.ClipStream clipStream, int width = 0)
        {
            if (clipStream.Stream == null)
            {
                return(null);
            }
            TryReset(clipStream.Stream);
            using var ms = new MemoryStream();
            clipStream.Stream.CopyTo(ms);
            TryReset(ms);
            using var bitmapSource = SKBitmap.Decode(ms);
            using var bitmapDest   = new SKBitmap(bitmapSource.Width, bitmapSource.Height, SKColorType.Bgra8888, SKAlphaType.Unpremul);

            using var canvas = new SKCanvas(bitmapDest);

            var rect = clipStream.Circle ?
                       new SKRect(0, 0, bitmapSource.Width, bitmapSource.Height) :
                       new SKRect(clipStream.Left, clipStream.Top, clipStream.Right, clipStream.Bottom);
            var roundRect = clipStream.Circle ?
                            new SKRoundRect(rect, bitmapSource.Width / 2f, bitmapSource.Height / 2f) :
                            new SKRoundRect(rect, clipStream.Radius_X, clipStream.Radius_Y);

            canvas.ClipRoundRect(roundRect, antialias: true);

            canvas.DrawBitmap(bitmapSource, 0, 0);

            var stream = bitmapDest.Encode(SKEncodedImageFormat.Png, 100).AsStream();

            TryReset(stream);

            //var tempFilePath = Path.Combine(IOPath.CacheDirectory, Path.GetFileName(Path.GetTempFileName() + ".png"));
            //using (var fs = File.Create(tempFilePath))
            //{
            //    stream.CopyTo(fs);
            //    TryReset(stream);
            //}

            return(GetDecodeBitmap(stream, width));
        }
Пример #5
0
        private RegisterIdentityViewModel CreateViewModelForRegister(bool photoUploadSucceeds)
        {
            SKBitmap bitmap = new SKBitmap(300, 300);
            string   path   = Path.Combine(Path.GetTempPath(), Folder);

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

            this.fullPath = Path.Combine(path, File);
            using (var data = bitmap.Encode(SKEncodedImageFormat.Jpeg, 100))
            {
                byte[] bytes = data.ToArray();
                using (FileStream fs = System.IO.File.OpenWrite(fullPath))
                {
                    fs.Write(bytes);
                }
            }

            this.neuronService.SetupGet(x => x.IsOnline).Returns(true);
            Guid guid = Guid.NewGuid();

            // Upload attachment
            this.identity = new LegalIdentity {
                Id = guid.ToString(), State = IdentityState.Approved
            };
            this.networkService.Setup(x => x.TryRequest(It.IsAny <Func <Task <LegalIdentity> > >(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <string>()))
            .Returns(Task.FromResult((photoUploadSucceeds, this.identity)));
            // Short circuit the begin invoke calls, so they're executed synchronously.
            this.dispatcher.Setup(x => x.BeginInvokeOnMainThread(It.IsAny <Action>())).Callback <Action>(x => x());
            this.tagProfile.SetupGet(x => x.HttpFileUploadMaxSize).Returns(short.MaxValue);
            this.tagProfile.SetupGet(x => x.LegalJid).Returns(Guid.NewGuid().ToString);
            this.tagProfile.SetupGet(x => x.RegistryJid).Returns(Guid.NewGuid().ToString);
            this.tagProfile.SetupGet(x => x.ProvisioningJid).Returns(Guid.NewGuid().ToString);

            return(AViewModel());
        }
Пример #6
0
        private static void __DrawGfx()
        {
            var rotated = new SKBitmap(1024, 1024);
            var info    = new SKRect(0, 0, 1024, 1024);

            using (SKCanvas canvas = new SKCanvas(rotated)) {
                using (SKPaint paint = new SKPaint
                {
                    Style = SKPaintStyle.Stroke,
                    Color = SKColors.Red,
                    StrokeWidth = 25,
                    IsAntialias = true
                })
                {
                    canvas.RotateDegrees(2);
                    canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
                    paint.Style = SKPaintStyle.Fill;
                    paint.Color = SKColors.Blue;
                    canvas.DrawCircle(info.Width / 2, info.Height / 2, 75, paint);

                    canvas.RotateDegrees(20);
                    canvas.DrawCircle(info.Width / 2, info.Height / 2, 50, paint);
                    paint.Style = SKPaintStyle.Fill;
                    paint.Color = SKColors.Yellow;
                    canvas.DrawCircle(info.Width / 2, info.Height / 2, 25, paint);

                    paint.Color = SKColors.Red;
                    canvas.ResetMatrix();
                    canvas.DrawOval(info.Width / 4, info.Height / 2, 25, 50, paint);
                }
            }
            using (var filstream = File.Open("xsj02_039_13_Gfx.png", FileMode.OpenOrCreate))
            {
                rotated.Encode(filstream, SKEncodedImageFormat.Png, 1);
            }
        }
Пример #7
0
        ///<inheritdoc/>
        public override Task InjectAsync(Stream source, Stream destination, Stream data, IProgress <double> progress = null, CancellationToken cancellationToken = default)
        {
            SKBitmap inputImage = SKBitmap.Decode(source);

            int width  = inputImage.Width;
            int height = inputImage.Height;

            List <byte> ls_data = new List <byte>();

            ls_data.AddRange(data.ReadAllBytes());

            if (Eof != null)
            {
                ls_data.AddRange(Eof);
            }

            BitArray message = new BitArray(ls_data.ToArray());

            int count = message.Count;

            if (EnsureSuccess)
            {
                int maxWritable = (UseAlphaChannel ? 4 : 3) * LsbDepth * width * height;

                if (count > maxWritable)
                {
                    throw new InsufficientSpaceException("A successful write cannot be ensured because the data is too large");
                }
            }

            SKBitmap outputImage = inputImage.Copy();

            int pos = 0;

            for (int y = 0; y < height; y++)
            {
                bool stop = false;
                for (int x = 0; x < width; x++)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                    }

                    if (pos == count)
                    {
                        stop = true;
                        break;
                    }

                    SKColor pixel = inputImage.GetPixel(x, y);

                    int[] vals = new int[] { pixel.Alpha, pixel.Red, pixel.Green, pixel.Blue };

                    for (int v = 0; v < vals.Length; v++)
                    {
                        if (!UseAlphaChannel && v == 0)
                        {
                            continue;
                        }

                        BitArray bitArray = new BitArray(new[] { vals[v] });
                        for (int i = 0; i < LsbDepth; i++)
                        {
                            if (pos == count)
                            {
                                stop = true;
                                break;
                            }

                            bitArray[i] = message[pos];
                            pos++;
                        }

                        vals[v] = (int)bitArray.ToULong();
                        if (stop)
                        {
                            break;
                        }
                    }

                    pixel = new SKColor((byte)vals[1], (byte)vals[2], (byte)vals[3], (byte)vals[0]);

                    outputImage.SetPixel(x, y, pixel);

                    if (progress != null)
                    {
                        progress.Report(pos / (double)count);
                    }
                }

                if (stop)
                {
                    break;
                }
            }

            outputImage.Encode(destination, SKEncodedImageFormat.Png, 100);

            return(Task.CompletedTask);
        }
Пример #8
0
        public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation?orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
        {
            if (string.IsNullOrWhiteSpace(inputPath))
            {
                throw new ArgumentNullException("inputPath");
            }
            if (string.IsNullOrWhiteSpace(inputPath))
            {
                throw new ArgumentNullException("outputPath");
            }

            var skiaOutputFormat = GetImageFormat(selectedOutputFormat);

            var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor);
            var hasForegroundColor = !string.IsNullOrWhiteSpace(options.ForegroundLayer);
            var blur         = options.Blur ?? 0;
            var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0);

            using (var bitmap = GetBitmap(inputPath, options.CropWhiteSpace, autoOrient, orientation))
            {
                if (bitmap == null)
                {
                    throw new ArgumentOutOfRangeException(string.Format("Skia unable to read image {0}", inputPath));
                }

                //_logger.Info("Color type {0}", bitmap.Info.ColorType);

                var originalImageSize = new ImageSize(bitmap.Width, bitmap.Height);

                if (!options.CropWhiteSpace && options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient)
                {
                    // Just spit out the original file if all the options are default
                    return(inputPath);
                }

                var newImageSize = ImageHelper.GetNewImageSize(options, originalImageSize);

                var width  = Convert.ToInt32(Math.Round(newImageSize.Width));
                var height = Convert.ToInt32(Math.Round(newImageSize.Height));

                using (var resizedBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
                {
                    // scale image
                    var resizeMethod = SKBitmapResizeMethod.Lanczos3;

                    bitmap.Resize(resizedBitmap, resizeMethod);

                    // If all we're doing is resizing then we can stop now
                    if (!hasBackgroundColor && !hasForegroundColor && blur == 0 && !hasIndicator)
                    {
                        _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
                        using (var outputStream = new SKFileWStream(outputPath))
                        {
                            resizedBitmap.Encode(outputStream, skiaOutputFormat, quality);
                            return(outputPath);
                        }
                    }

                    // create bitmap to use for canvas drawing
                    using (var saveBitmap = new SKBitmap(width, height))//, bitmap.ColorType, bitmap.AlphaType))
                    {
                        // create canvas used to draw into bitmap
                        using (var canvas = new SKCanvas(saveBitmap))
                        {
                            // set background color if present
                            if (hasBackgroundColor)
                            {
                                canvas.Clear(SKColor.Parse(options.BackgroundColor));
                            }

                            // Add blur if option is present
                            if (blur > 0)
                            {
                                using (var paint = new SKPaint())
                                {
                                    // create image from resized bitmap to apply blur
                                    using (var filter = SKImageFilter.CreateBlur(blur, blur))
                                    {
                                        paint.ImageFilter = filter;
                                        canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height), paint);
                                    }
                                }
                            }
                            else
                            {
                                // draw resized bitmap onto canvas
                                canvas.DrawBitmap(resizedBitmap, SKRect.Create(width, height));
                            }

                            // If foreground layer present then draw
                            if (hasForegroundColor)
                            {
                                Double opacity;
                                if (!Double.TryParse(options.ForegroundLayer, out opacity))
                                {
                                    opacity = .4;
                                }

                                canvas.DrawColor(new SKColor(0, 0, 0, (Byte)((1 - opacity) * 0xFF)), SKBlendMode.SrcOver);
                            }

                            if (hasIndicator)
                            {
                                DrawIndicator(canvas, width, height, options);
                            }

                            _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(outputPath));
                            using (var outputStream = new SKFileWStream(outputPath))
                            {
                                saveBitmap.Encode(outputStream, skiaOutputFormat, quality);
                            }
                        }
                    }
                }
            }
            return(outputPath);
        }
Пример #9
0
 public void SaveImage(SKBitmap image, Stream stream)
 {
     image.Encode(stream, SKEncodedImageFormat.Jpeg, Quality);
 }
Пример #10
0
        private async void ImageButton_Clicked_2(object sender, EventArgs e)
        {
            if (loading.Count == 0)
            {
                isRunning = true;
                string fileName = await DisplayPromptAsync("Save", "What would you like the file name to be?", "OK", "Cancel", "File Name");


                //Gives option to save file with a custom name on photo gallery

                if (fileName != null && fileName != "" && fileName != "Cancel" && fileName != "OK")
                {
                    option = await DisplayActionSheet("Quality", null, null, "Custom", "Max High", "Ultra High", "High", "Medium", "Low", "Very Low");

                    Option_Check();

                    cancel = false;

                    canvasImage.IsVisible     = true;
                    canvasImageFast.IsVisible = false;

                    loading.Add("Loading . . . ");

                    double ri;
                    double ci;
                    double l;

                    string downloadMacro;
                    string downloadMicro;

                    if (createAdvanced)
                    {
                        downloadMacro = macroInput;
                        downloadMicro = microInput;

                        ri = realInput;
                        ci = complexInput;
                        l  = lengthInput;
                    }
                    else
                    {
                        downloadMacro = selectedColor;
                        downloadMicro = selecterColorMicro;

                        if (item <= integer - 1)
                        {
                            ri = varList1[item];
                            ci = varList2[item];
                            l  = varList3[item];
                        }
                        else
                        {
                            ri = SavedFractals[item - integer].SavedReal;
                            ci = SavedFractals[item - integer].SavedComplex;
                            l  = SavedFractals[item - integer].SavedLength;
                        }
                    }

                    double riCache = ri;
                    double ciCache = ci;

                    if (item >= 12 && item <= 15)
                    {
                        ri = 0.2;
                        ci = 0;
                        l  = 1;
                    }

                    else if (item > integer - 1)
                    {
                        if (SavedFractals[item - integer].IsJuliaSet)
                        {
                            ri = 0.2;
                            ci = 0;
                            l  = 1;
                        }
                    }

                    else
                    {
                        julia = -1;
                    }

                    //Making 2x2 array with size height export and width export
                    Complex complix;
                    Pixel[,] picture = new Pixel[heightExport, widthExport];
                    int a;
                    int b;

                    //Setting format to Jpeg

                    SKEncodedImageFormat imageFormat = SKEncodedImageFormat.Jpeg;
                    int quality = 100;

                    //For loop with calculations, every column calulated between loading changes
                    //i goes up by the length value to make proportional
                    for (double i = ri * heightExport; i < (ri + l) * heightExport; i += l)
                    {
                        if (cancel)
                        {
                            break;
                        }
                        Loading();

                        for (double j = ci * widthExport; j < (ci + l) * widthExport; j += l)
                        {
                            if (cancel)
                            {
                                break;
                            }

                            //setting shift of and position
                            a = (int)((i - ri * heightExport) / l);
                            b = (int)((j - ci * widthExport) / l);

                            complix = new Complex((i - (14 * heightExport / 20.0)) / (widthExport / 3.0), (j - (widthExport / 2.0)) / (heightExport / 3.0 * widthExport / heightExport));

                            int onoff = (int)(Iterate(complix, item, riCache, ciCache) * 255);

                            updatePixelInputs(downloadMacro, downloadMicro, onoff);

                            picture[a, b] = new Pixel(intInput1, intInput2, intInput3);

                            //Sets individual pixels
                            if (picture[a, b] == null)
                            {
                                picture[a, b] = new Pixel(0, 0, 0);

                                SKColor colorPixelNull = new SKColor((byte)picture[a, b].GetRed(), (byte)picture[a, b].GetGreen(), (byte)picture[a, b].GetBlue());

                                bitmap.SetPixel(a, b, colorPixelNull);
                            }
                            else
                            {
                                SKColor colorPixel = new SKColor((byte)picture[a, b].GetRed(), (byte)picture[a, b].GetGreen(), (byte)picture[a, b].GetBlue());

                                bitmap.SetPixel(a, b, colorPixel);
                            }
                        }

                        //Saves image every column
                        using (MemoryStream memStream = new MemoryStream())
                            using (SKManagedWStream wstream = new SKManagedWStream(memStream))
                            {
                                bitmap.Encode(wstream, imageFormat, quality);

                                byte[] data = memStream.ToArray();

                                if (data != null && data.Length != 0)
                                {
                                    await DependencyService.Get <IPhotoLibrary>().
                                    SavePhotoAsync(data, "SaveFileFormats", fileName + ".Jpeg");
                                }
                            }
                    }

                    cancel = false;
                }
                heightExport = (int)(Settings.QualityOptions[0].Quality);
                widthExport  = (int)(Settings.QualityOptions[0].Quality);
                if (loading.Count != 0)
                {
                    loading.RemoveAt(0);
                }
                isRunning = false;
            }
        }
Пример #11
0
 /// <summary>
 /// Export image to stream.
 /// </summary>
 /// <param name="stream">Stream to export the image to..</param>
 /// <param name="format">Format for the encoding.</param>
 /// <returns>Byte array.</returns>
 public void ExportToStream(Stream stream, Format format)
 {
     bitmap.Encode(stream, format.ToSkiaFormat(), 100);
 }
Пример #12
0
 void Save(string destination, SKBitmap tempBitmap)
 {
     using var stream = File.Create(destination);
     tempBitmap.Encode(stream, SKEncodedImageFormat.Png, 100);
 }
 /// <inheritdoc cref="ToPng(QrCode, int, int)"/>
 /// <param name="background">The background color.</param>
 /// <param name="foreground">The foreground color.</param>
 public static byte[] ToPng(this QrCode qrCode, int scale, int border, SKColor foreground, SKColor background)
 {
     using SKBitmap bitmap = qrCode.ToBitmap(scale, border, foreground, background);
     using SKData data     = bitmap.Encode(SKEncodedImageFormat.Png, 90);
     return(data.ToArray());
 }
Пример #14
0
        public byte[] DrawAreaAtSize(ImageStats stats, List <CompletePaintOp> paintOps)
        {
            //This is the new core drawing function. Once the paint operations have been created, I just draw them here.
            //baseline image data stuff
            SKBitmap bitmap = new SKBitmap(stats.imageSizeX, stats.imageSizeY, SKColorType.Rgba8888, SKAlphaType.Premul);
            SKCanvas canvas = new SKCanvas(bitmap);

            canvas.Clear(eraser.Color);
            canvas.Scale(1, -1, stats.imageSizeX / 2, stats.imageSizeY / 2);
            SKPaint paint = new SKPaint();

            foreach (var w in paintOps.OrderByDescending(p => p.paintOp.LayerId).ThenByDescending(p => p.areaSize))
            {
                paint = cachedPaints[w.paintOp.Id]; //SetPaintForTPP(w.paintOp); // w.paintOp.paint;

                if (w.paintOp.FromTag)              //FromTag is for when you are saving color data directly to each element, instead of tying it to a styleset.
                {
                    paint.Color = SKColor.Parse(w.tagValue);
                }

                if (w.paintOp.Randomize) //To randomize the color on every Draw call.
                {
                    paint.Color = new SKColor((byte)r.Next(0, 255), (byte)r.Next(0, 255), (byte)r.Next(0, 255), 99);
                }

                paint.StrokeWidth = (float)w.lineWidthPixels;
                var path = new SKPath();
                switch (w.elementGeometry.GeometryType)
                {
                case "Polygon":
                    var p = w.elementGeometry as Polygon;
                    //if (p.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                    //continue;
                    path.AddPoly(PolygonToSKPoints(p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                    foreach (var ir in p.Holes)
                    {
                        //if (ir.Envelope.Length < (w.lineWidth * 4)) //This poly's perimeter is less than 2x2 pixels in size.
                        //continue;
                        path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                    }
                    canvas.DrawPath(path, paint);
                    break;

                case "MultiPolygon":
                    foreach (var p2 in ((MultiPolygon)w.elementGeometry).Geometries)
                    {
                        //if (p2.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                        //continue;
                        var p2p = p2 as Polygon;
                        path.AddPoly(PolygonToSKPoints(p2p.ExteriorRing, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                        foreach (var ir in p2p.Holes)
                        {
                            //if (ir.Envelope.Length < (stats.degreesPerPixelX * 4)) //This poly's perimeter is too small to draw
                            // continue;
                            path.AddPoly(PolygonToSKPoints(ir, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY));
                        }
                        canvas.DrawPath(path, paint);
                    }
                    break;

                case "LineString":
                    var firstPoint = w.elementGeometry.Coordinates.First();
                    var lastPoint  = w.elementGeometry.Coordinates.Last();
                    var points     = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                    if (firstPoint.Equals(lastPoint))
                    {
                        //This is a closed shape. Check to see if it's supposed to be filled in.
                        if (paint.Style == SKPaintStyle.Fill)
                        {
                            path.AddPoly(points);
                            canvas.DrawPath(path, paint);
                            continue;
                        }
                    }
                    //if (w.lineWidth < 1) //Don't draw lines we can't see.
                    //continue;
                    for (var line = 0; line < points.Length - 1; line++)
                    {
                        canvas.DrawLine(points[line], points[line + 1], paint);
                    }
                    break;

                case "MultiLineString":
                    //if (w.lineWidth < 1) //Don't draw lines we can't see.
                    //continue;
                    foreach (var p3 in ((MultiLineString)w.elementGeometry).Geometries)
                    {
                        var points2 = PolygonToSKPoints(p3, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                        for (var line = 0; line < points2.Length - 1; line++)
                        {
                            canvas.DrawLine(points2[line], points2[line + 1], paint);
                        }
                    }
                    break;

                case "Point":
                    var convertedPoint = PolygonToSKPoints(w.elementGeometry, stats.area, stats.degreesPerPixelX, stats.degreesPerPixelY);
                    //If this type has an icon, use it. Otherwise draw a circle in that type's color.
                    if (!string.IsNullOrEmpty(w.paintOp.FileName))
                    {
                        SKBitmap icon = SKBitmap.Decode(TagParser.cachedBitmaps[w.paintOp.FileName]);     //TODO optimize by making icons in Initialize.
                        canvas.DrawBitmap(icon, convertedPoint[0]);
                    }
                    else
                    {
                        var circleRadius = (float)(ConstantValues.resolutionCell10 / stats.degreesPerPixelX / 2);     //I want points to be drawn as 1 Cell10 in diameter.
                        canvas.DrawCircle(convertedPoint[0], circleRadius, paint);
                        //TODO re-add outline paint to this DLL not TagParser.
                        //canvas.DrawCircle(convertedPoint[0], circleRadius, TagParser.outlinePaint);
                    }
                    break;

                default:
                    Log.WriteLog("Unknown geometry type found, not drawn.");
                    break;
                }
            }
            //}

            var ms   = new MemoryStream();
            var skms = new SKManagedWStream(ms);

            bitmap.Encode(skms, SKEncodedImageFormat.Png, 100);
            var results = ms.ToArray();

            skms.Dispose(); ms.Close(); ms.Dispose();
            return(results);
        }
Пример #15
0
        async void OnCanvasViewTapped(object sender, EventArgs e)
        {
            List <string> scenes = new List <string>();
            string        action = await DisplayActionSheet("What to do?", null, null, "Load Scene", "Save Scene", "Delete Scene", "Render Scene");

            if (action == "Load Scene")
            {
                var sceneDescs = db.Table <SceneDescription>();
                foreach (var item in sceneDescs)
                {
                    scenes.Add(item.sceneName);
                }
                string whatToLoad = await DisplayActionSheet("Which scene to load?", null, null, scenes.ToArray());

                if (whatToLoad != null)
                {
                    sc.LoadScene(whatToLoad);
                    sc.SetMainCamera(GetCameraFromEntry());
                    LoadShapesIntoOC();
                    LoadLightsIntoOC();
                }
            }
            else if (action == "Save Scene")
            {
                string sceneName = await DisplayPromptAsync("Save Scene", "Scene name:");

                sc.SaveScene(sceneName);
            }
            else if (action == "Delete Scene")
            {
                var sceneDescs = db.Table <SceneDescription>();
                foreach (var item in sceneDescs)
                {
                    scenes.Add(item.sceneName);
                }
                string whatToDelete = await DisplayActionSheet("Which scene to load?", null, null, scenes.ToArray());

                if (whatToDelete != null)
                {
                    sc.DeleteScene(whatToDelete);
                }
            }
            else if (action == "Render Scene")
            {
                bigImage = new SKBitmap(1024, 1024);
                sc.mainCamera.finishedRendering = false;
                sc.mainCamera.Render(bigImage);
                Toast.MakeText(Android.App.Application.Context, "Rendering, please wait! (it may take a loooong time)", ToastLength.Long).Show();
                while (!sc.mainCamera.finishedRendering)
                {
                    Console.WriteLine("still busy");
                    await Task.Delay(25);
                }
                try
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        using (SKManagedWStream wstream = new SKManagedWStream(ms))
                        {
                            bigImage.Encode(wstream, SKEncodedImageFormat.Png, 100);
                            byte[] data   = ms.ToArray();
                            var    status = await CrossPermissions.Current.CheckPermissionStatusAsync <StoragePermission>();

                            if (status != Plugin.Permissions.Abstractions.PermissionStatus.Granted)
                            {
                                await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Plugin.Permissions.Abstractions.Permission.Storage);

                                status = await CrossPermissions.Current.RequestPermissionAsync <StoragePermission>();
                            }
                            if (status == Plugin.Permissions.Abstractions.PermissionStatus.Granted)
                            {
                                string filename = DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".png";
                                if (!Directory.Exists(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer"))
                                {
                                    Directory.CreateDirectory(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer");
                                }
                                if (File.Exists(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer/" + filename))
                                {
                                    File.Delete(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer/" + filename);
                                }

                                using (var stream = File.Create(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer/" + filename))
                                {
                                    stream.Write(data, 0, data.Length);
                                    Toast.MakeText(Android.App.Application.Context, "Finished rendering!, saved to " + Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/DCIM/xTracer/" + filename, ToastLength.Long).Show();
                                }
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// 内部使用
        /// </summary>
        private async Task <ISharedImageMessage> InternalUploadPictureAsync(InternalSessionInfo session, UploadTarget type, Stream imgStream, bool disposeStream, CancellationToken token = default)
        {
            // 使用 disposeStream 目的是不使上层 caller 创建多余的状态机
            if (session.ApiVersion <= new Version(1, 7, 0))
            {
                Guid         guid = Guid.NewGuid();
                MemoryStream ms   = new MemoryStream(8192); // 无论如何都做一份copy
                await imgStream.CopyToAsync(ms, 81920, token).ConfigureAwait(false);

                ImageHttpListener.RegisterImage(guid, ms);
                return(new ImageMessage(null, $"http://127.0.0.1:{ImageHttpListener.Port}/fetch?guid={guid:n}", null));
            }
            Stream?internalStream  = null;
            bool   internalCreated = false;
            long   pervious        = 0;

            if (!imgStream.CanSeek || imgStream.CanTimeout) // 对于 CanTimeOut 的 imgStream, 或者无法Seek的, 一律假定其读取行为是阻塞的
                                                            // 为其创建一个内部缓存先行异步读取
            {
                internalStream  = new MemoryStream(8192);
                internalCreated = true;
                await imgStream.CopyToAsync(internalStream, 81920, token);

                internalStream.Seek(0, SeekOrigin.Begin);
            }
            else // 否则不创建副本, 避免多余的堆分配
            {
                internalStream = imgStream;
                pervious       = imgStream.Position;
            }
            HttpContent sessionKeyContent = new StringContent(session.SessionKey);

            sessionKeyContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "sessionKey"
            };
            HttpContent typeContent = new StringContent(type.ToString().ToLower());

            typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "type"
            };
            string format;

            using SKManagedStream skstream = new SKManagedStream(internalStream, false);
            using (SKCodec codec = SKCodec.Create(skstream)) // 已经把数据读到非托管内存里边了, 就不用管input的死活了
            {
                var skformat = codec.EncodedFormat;
                format = skformat.ToString().ToLower();
                switch (skformat)
                {
                case SKEncodedImageFormat.Gif:
                case SKEncodedImageFormat.Jpeg:
                case SKEncodedImageFormat.Png:
                    break;

                default:
                {
                    skstream.Seek(0);
                    using (SKBitmap bitmap = SKBitmap.Decode(skstream))
                    {
                        if (!internalCreated)
                        {
                            internalStream  = new MemoryStream(8192);
                            internalCreated = true;
                        }
                        else
                        {
                            internalStream.Seek(0, SeekOrigin.Begin);
                        }
                        bitmap.Encode(internalStream, SKEncodedImageFormat.Png, 100);
                    }
                    format = "png";
                    break;
                }
                }
            }
            if (internalCreated)
            {
                internalStream.Seek(0, SeekOrigin.Begin);
            }
            else // internalStream == imgStream
            {
                internalStream.Seek(pervious - internalStream.Position, SeekOrigin.Current);
            }
            HttpContent imageContent = new StreamContent(internalStream);

            imageContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name     = "img",
                FileName = $"{Guid.NewGuid():n}.{format}"
            };
            imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + format);
            HttpContent[] contents = new HttpContent[]
            {
                sessionKeyContent,
                typeContent,
                imageContent
            };
            try
            {
                CreateLinkedUserSessionToken(session.Token, token, out CancellationTokenSource? cts, out token);
                return(await _client.PostAsync($"{_options.BaseUrl}/uploadImage", contents, token)
                       .AsApiRespAsync <ISharedImageMessage, ImageMessage>(token)
                       .DisposeWhenCompleted(cts)
                       .ContinueWith(t => t.IsFaulted && t.Exception !.InnerException is JsonException ? throw new NotSupportedException("当前版本的mirai-api-http无法发送图片。") : t, TaskContinuationOptions.ExecuteSynchronously).Unwrap().ConfigureAwait(false));

                //  ^-- 处理 JsonException 到 NotSupportedException, https://github.com/mamoe/mirai-api-http/issues/85
                // internalStream 是 MemoryStream, 内部为全托管字段不需要 Dispose
            }
            finally
            {
                if (disposeStream)
                {
                    imgStream.Dispose();
                }
            }
        }
        /// <summary>
        /// 内部使用
        /// </summary>
        /// <exception cref="InvalidOperationException"/>
        /// <param name="type">目标类型</param>
        /// <param name="imgStream">图片流</param>
        /// <remarks>
        /// 注意: 当 mirai-api-http 的版本小于等于v1.7.0时, 本方法返回的将是一个只有 Url 有值的 <see cref="ImageMessage"/>
        /// </remarks>
        /// <returns>一个 <see cref="ImageMessage"/> 实例, 可用于以后的消息发送</returns>
        private static Task <ImageMessage> InternalUploadPictureAsync(InternalSessionInfo session, UploadTarget type, Stream imgStream)
        {
            if (session.ApiVersion <= new Version(1, 7, 0))
            {
                Guid guid = Guid.NewGuid();
                ImageHttpListener.RegisterImage(guid, imgStream);
                return(Task.FromResult(new ImageMessage(null, $"http://127.0.0.1:{ImageHttpListener.Port}/fetch?guid={guid:n}", null)));
            }
            HttpContent sessionKeyContent = new StringContent(session.SessionKey);

            sessionKeyContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "sessionKey"
            };
            HttpContent typeContent = new StringContent(type.ToString().ToLower());

            typeContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name = "type"
            };
            string format;

            using MemoryStream codecMemoryStream = new MemoryStream();
            imgStream.CopyTo(codecMemoryStream);
            codecMemoryStream.Seek(0, SeekOrigin.Begin);
            using (SKCodec codec = SKCodec.Create(codecMemoryStream))
            {
                var skformat = codec.EncodedFormat;
                format = skformat.ToString().ToLower();
                switch (skformat)
                {
                case SKEncodedImageFormat.Gif:
                case SKEncodedImageFormat.Jpeg:
                case SKEncodedImageFormat.Png:
                    break;

                default:
                    imgStream.Seek(0, SeekOrigin.Begin);
                    using (SKBitmap bitmap = SKBitmap.Decode(imgStream))
                    {
                        MemoryStream ms = new MemoryStream();
                        bitmap.Encode(ms, SKEncodedImageFormat.Png, 100);
                        imgStream = ms;
                        format    = SKEncodedImageFormat.Png.ToString().ToLower();
                    }
                    break;
                }
            }
            imgStream.Seek(0, SeekOrigin.Begin);
            HttpContent imageContent = new StreamContent(imgStream);

            imageContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
            {
                Name     = "img",
                FileName = $"{Guid.NewGuid():n}.{format}"
            };
            imageContent.Headers.ContentType = new MediaTypeHeaderValue("image/" + format);
            HttpContent[] contents = new HttpContent[]
            {
                sessionKeyContent,
                typeContent,
                imageContent
            };
            return(session.Client.PostAsync($"{session.Options.BaseUrl}/uploadImage", contents, session.Token)
                   .AsNoSuccCodeApiRespAsync <ImageMessage>(session.Token)
                   .ContinueWith(t => t.IsFaulted && t.Exception !.InnerException is JsonException ? throw new NotSupportedException("当前版本的mirai-api-http无法发送图片。") : t, TaskContinuationOptions.ExecuteSynchronously).Unwrap());
            //  ^-- 处理 JsonException 到 NotSupportedException, https://github.com/mamoe/mirai-api-http/issues/85
        }
Пример #18
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));
        }
Пример #19
0
        public ResizedImageInfo Resize(DpiPath dpi, string destination, Func <Stream> getStream = null)
        {
            var sw = new Stopwatch();

            sw.Start();

            var(bgScaledSize, bgScale) = backgroundTools.GetScaledSize(backgroundOriginalSize, dpi);

            // Make the canvas size match the desired size
            var canvasSize = bgScaledSize;

            if (dpi.Size is SKSize size && size.Width != size.Height)
            {
                var scale = (float)dpi.Scale;
                canvasSize = new SKSizeI((int)(size.Width * scale), (int)(size.Height * scale));
            }

            // Allocate
            using (var tempBitmap = new SKBitmap(canvasSize.Width, canvasSize.Height))
            {
                // Draw (copy)
                using (var canvas = new SKCanvas(tempBitmap))
                {
                    canvas.Clear(Info.Color ?? SKColors.Transparent);
                    canvas.Save();
                    canvas.Translate(
                        (canvasSize.Width - bgScaledSize.Width) / 2,
                        (canvasSize.Height - bgScaledSize.Height) / 2);
                    canvas.Scale(bgScale, bgScale);

                    backgroundTools.DrawUnscaled(canvas, bgScale);
                    canvas.Restore();

                    if (hasForeground)
                    {
                        var userFgScale = (float)Info.ForegroundScale;

                        // get the ratio to make the foreground fill the background
                        var fitRatio = bgScaledSize.Width / foregroundOriginalSize.Width;

                        // calculate the scale for the foreground to fit the background exactly
                        var(fgScaledSize, fgScale) = foregroundTools.GetScaledSize(foregroundOriginalSize, (decimal)fitRatio);

                        //Logger.Log("\tdpi.Size: " + dpi.Size);
                        //Logger.Log("\tdpi.Scale: " + dpi.Scale);
                        //Logger.Log("\tbgScaledSize: " + bgScaledSize);
                        //Logger.Log("\tbgScale: " + bgScale);
                        //Logger.Log("\tforegroundOriginalSize: " + foregroundOriginalSize);
                        //Logger.Log("\tfgScaledSize: " + fgScaledSize);
                        //Logger.Log("\tfgScale: " + fgScale);
                        //Logger.Log("\tuserFgScale: " + userFgScale);

                        // now work out the center as if the canvas was exactly the same size as the foreground
                        var fgScaledSizeCenterX = foregroundOriginalSize.Width / 2;
                        var fgScaledSizeCenterY = foregroundOriginalSize.Height / 2;

                        //Logger.Log("\tfgScaledSizeCenterX: " + fgScaledSizeCenterX);
                        //Logger.Log("\tfgScaledSizeCenterY: " + fgScaledSizeCenterY);

                        // center the foreground
                        canvas.Translate(
                            (canvasSize.Width - fgScaledSize.Width) / 2,
                            (canvasSize.Height - fgScaledSize.Height) / 2);

                        // scale so the forground is the same size as the background
                        canvas.Scale(fgScale, fgScale);

                        // scale to the user scale, centering
                        canvas.Scale(userFgScale, userFgScale, fgScaledSizeCenterX, fgScaledSizeCenterY);

                        foregroundTools.DrawUnscaled(canvas, fgScale * userFgScale);
                    }
                }

                // Save (encode)
                if (getStream is not null)
                {
                    var stream = getStream();
                    tempBitmap.Encode(stream, SKEncodedImageFormat.Png, 100);
                }
                else
                {
                    using var wrapper = File.Create(destination);
                    tempBitmap.Encode(wrapper, SKEncodedImageFormat.Png, 100);
                }
            }

            sw.Stop();
            Logger?.Log($"Save app icon took {sw.ElapsedMilliseconds}ms ({destination})");

            return(new ResizedImageInfo {
                Dpi = dpi, Filename = destination
            });
        }
Пример #20
0
        public async void GenerateMandelbrotZoom(double ri, double ci, double l, string macroColor, string microColor, int index)
        {
            double riCache = ri;
            double ciCache = ci;

            if (index >= 12 && index <= 15)
            {
                ri = 0.2;
                ci = 0;
                l  = 1;
            }

            else if (index > integer - 1)
            {
                if (SavedFractals[item - integer].IsJuliaSet)
                {
                    ri = 0.2;
                    ci = 0;
                    l  = 1;
                }
            }
            else if (index == -2)
            {
                ri = 0.2;
                ci = 0;
                l  = 1;
            }
            else
            {
                julia = -1;
            }

            if (loading.Count == 0)
            {
                isRunning = true;
                cancel    = false;

                canvasImage.IsVisible = false;

                loading.Add("Loading . . . ");

                bitmapFast = new SKBitmap(widthExport, heightExport, true);

                canvasImageFast.IsVisible = true;

                cancel = false;
                //Making 2x2 array with size height export and width export
                Complex complix;
                Pixel[,] picture = new Pixel[widthExport, heightExport];
                int a;
                int b;

                //Setting format to Jpeg

                SKEncodedImageFormat imageFormat = SKEncodedImageFormat.Jpeg;
                int quality = 100;

                //For loop with calculations, every column calulated between loading changes
                //i goes up by the length value to make proportional

                for (double i = ri * widthExport; i < (ri + l) * widthExport; i += l)
                {
                    if (cancel)
                    {
                        break;
                    }
                    for (double j = ci * heightExport; j < (ci + l) * heightExport; j += l)
                    {
                        if (cancel)
                        {
                            break;
                        }

                        //setting shift of and position
                        a = (int)((i - ri * widthExport) / l);
                        b = (int)((j - ci * heightExport) / l);

                        complix = new Complex((i - (14 * heightExport / 20.0)) / (widthExport / 3.0), (j - (widthExport / 2.0)) / (heightExport / 3.0 * widthExport / heightExport));

                        int onoff = (int)(Iterate(complix, index, riCache, ciCache) * 255);

                        updatePixelInputs(macroColor, microColor, onoff);

                        picture[a, b] = new Pixel(intInput1, intInput2, intInput3);

                        //Sets individual pixels
                        if (picture[a, b] == null)
                        {
                            picture[a, b] = new Pixel(0, 0, 0);

                            SKColor colorPixelNull = new SKColor((byte)picture[a, b].GetRed(), (byte)picture[a, b].GetGreen(), (byte)picture[a, b].GetBlue());

                            bitmapFast.SetPixel(a, b, colorPixelNull);
                        }
                        else
                        {
                            SKColor colorPixel = new SKColor((byte)picture[a, b].GetRed(), (byte)picture[a, b].GetGreen(), (byte)picture[a, b].GetBlue());

                            bitmapFast.SetPixel(a, b, colorPixel);
                        }
                    }
                    //Saves image every column
                    using (MemoryStream memStream = new MemoryStream())
                        using (SKManagedWStream wstream = new SKManagedWStream(memStream))
                        {
                            bitmapFast.Encode(wstream, imageFormat, quality);

                            byte[] data = memStream.ToArray();

                            if (data != null && data.Length != 0)
                            {
                                string fileName = null;
                                await DependencyService.Get <IPhotoLibrary>().
                                SavePhotoAsync(data, "SaveFileFormats", fileName + ".Jpeg");
                            }
                        }
                    Loading();
                }
                loading.RemoveAt(0);
                isRunning = false;
            }
        }
Пример #21
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));
        }
Пример #22
0
 public void SaveImage(SKBitmap image, Stream stream)
 {
     image.Encode(stream, SKEncodedImageFormat.Gif, 85);
 }
Пример #23
0
 static void save(SKBitmap image, string file)
 {
     using var stream = File.OpenWrite(file);
     image.Encode(stream, SKEncodedImageFormat.Png, 9);
 }
Пример #24
0
 private static void SaveImage(string filename, SKBitmap bitmap)
 {
     using var stream = File.OpenWrite(filename);
     bitmap.Encode(stream, SKEncodedImageFormat.Png, 0);
 }
Пример #25
0
        private async Task DrawPreview()
        {
            AddButton.IsEnabled       = false;
            UpButton.IsEnabled        = false;
            DownButton.IsEnabled      = false;
            DeleteButton.IsEnabled    = false;
            ClearButton.IsEnabled     = false;
            SizeSlider.IsEnabled      = false;
            OpenImageButton.IsEnabled = false;
            SaveImageButton.IsEnabled = false;

            var margin = UserSettings.Default.ImageMergerMargin;
            int num = 1, curW = 0, curH = 0, maxWidth = 0, maxHeight = 0, lineMaxHeight = 0, imagesPerRow = Convert.ToInt32(SizeSlider.Value);
            var positions = new Dictionary <int, SKPoint>();
            var images    = new SKBitmap[ImagesListBox.Items.Count];

            for (var i = 0; i < images.Length; i++)
            {
                var item   = (ListBoxItem)ImagesListBox.Items[i];
                var ms     = new MemoryStream();
                var stream = new FileStream(item.ContentStringFormat, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                if (item.ContentStringFormat.EndsWith(".tif"))
                {
                    await using var tmp = new MemoryStream();
                    await stream.CopyToAsync(tmp);

                    System.Drawing.Image.FromStream(tmp).Save(ms, ImageFormat.Png);
                }
                else
                {
                    await stream.CopyToAsync(ms);
                }

                var image = SKBitmap.Decode(ms.ToArray());
                positions[i] = new SKPoint(curW, curH);
                images[i]    = image;

                if (image.Height > lineMaxHeight)
                {
                    lineMaxHeight = image.Height;
                }

                if (num % imagesPerRow == 0)
                {
                    maxWidth = curW + image.Width + margin;
                    curH    += lineMaxHeight + margin;

                    curW          = 0;
                    lineMaxHeight = 0;
                }
                else
                {
                    maxHeight = curH + lineMaxHeight + margin;
                    curW     += image.Width + margin;
                    if (curW > maxWidth)
                    {
                        maxWidth = curW;
                    }
                }

                num++;
            }

            await Task.Run(() =>
            {
                using var bmp    = new SKBitmap(maxWidth - margin, maxHeight - margin, SKColorType.Rgba8888, SKAlphaType.Premul);
                using var canvas = new SKCanvas(bmp);

                for (var i = 0; i < images.Length; i++)
                {
                    using (images[i])
                    {
                        canvas.DrawBitmap(images[i], positions[i], new SKPaint {
                            FilterQuality = SKFilterQuality.High, IsAntialias = true
                        });
                    }
                }

                using var data   = bmp.Encode(SKEncodedImageFormat.Png, 100);
                using var stream = new MemoryStream(_imagebuffer = data.ToArray());
                var photo        = new BitmapImage();
                photo.BeginInit();
                photo.CacheOption  = BitmapCacheOption.OnLoad;
                photo.StreamSource = stream;
                photo.EndInit();
                photo.Freeze();

                Application.Current.Dispatcher.Invoke(delegate { ImagePreview.Source = photo; });
            }).ContinueWith(t =>
            {
                AddButton.IsEnabled       = true;
                UpButton.IsEnabled        = true;
                DownButton.IsEnabled      = true;
                DeleteButton.IsEnabled    = true;
                ClearButton.IsEnabled     = true;
                SizeSlider.IsEnabled      = true;
                OpenImageButton.IsEnabled = true;
                SaveImageButton.IsEnabled = true;
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }