Exemple #1
0
        public static (SKSizeI Scaled, SKSize Unscaled) GetCanvasSize(DpiPath dpi, SKSize?baseSize = null, SkiaSharpTools baseTools = null)
        {
            // if an explicit size was given by the type of image, use that
            if (dpi.Size is SKSize size)
            {
                var scale  = (float)dpi.Scale;
                var scaled = new SKSizeI(
                    (int)(size.Width * scale),
                    (int)(size.Height * scale));
                return(scaled, size);
            }

            // if an explicit size was given in the csproj, use that
            if (baseSize is SKSize bs)
            {
                var scale  = (float)dpi.Scale;
                var scaled = new SKSizeI(
                    (int)(bs.Width * scale),
                    (int)(bs.Height * scale));
                return(scaled, bs);
            }

            // try determine the best size based on the loaded image
            if (baseTools is not null)
            {
                var baseOriginalSize = baseTools.GetOriginalSize();
                var(baseScaledSize, _) = baseTools.GetScaledSize(baseOriginalSize, dpi.Scale);
                return(baseScaledSize, baseOriginalSize);
            }

            throw new InvalidOperationException("The canvas size cannot be calculated if there is no size to start from (DPI size, BaseSize or image size).");
        }
        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
            });
        }