前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >dotnet C# 图片等比限制最大和最小大小缩放算法

dotnet C# 图片等比限制最大和最小大小缩放算法

作者头像
林德熙
发布2020-05-12 17:08:53
1.8K0
发布2020-05-12 17:08:53
举报
文章被收录于专栏:林德熙的博客林德熙的博客

本文只是告诉大家如何计算缩放之后的宽度和高度,不包含实际的图片缩放方法

如下图,我要将图片的大小进行等比缩放,此时我要求图片的宽度和高度大于最小尺寸,但是要求宽度和高度都不大于最大尺寸,如果这两个规则冲突,优先满足不大于最大尺寸

按照规则可以看到,如下图,图片的宽度等于最大宽度了,此时虽然图片的高度小于最小高度,但是也不应该对图片进行缩放

为什么需要有最大限制?原因是等比缩放对于长图计算不友好,如果我有一张图片的宽度和高度比例是 1:1000 那么此时如果没有限制最大高度,那么将宽度缩放到最小宽度需要缩放10倍,此时的高度就太大了

下面就是计算方法

先定义大小这个类

代码语言:javascript
复制
    public class Size
    {
        public Size(double width, double height)
        {
            Width = width;
            Height = height;
        }

        public double Width { set; get; }
        public double Height { set; get; }

        /// <inheritdoc />
        public override string ToString()
        {
            return $"Width={Width:0.00} Height={Height:0.00}";
        }
    }

计算的方法需要传入当前图片的宽度和高度,最小的宽度和高度和最大的宽度和高度,返回的值是计算的宽度和高度

代码语言:javascript
复制
        static Size OptimizationSize(Size currentSize, Size minSize, Size maxSize)

计算的方法就是先获取宽度和高度的缩放到最小大小的缩放值

代码语言:javascript
复制
            var height = currentSize.Height;
            var width = currentSize.Width;
            var widthScale = minSize.Width / width;
            var heightScale = minSize.Height / height;

如果此时的图片本来就大于最小宽度和高度,就不能让图片的缩放比原来小,除非大于最大宽度或高度

代码语言:javascript
复制
            var minScale = Math.Max(widthScale, heightScale);
            minScale = Math.Max(minScale, 1.0);

计算图片和最大宽度和高度的缩放,同时拿到最大缩放里面的最小的一个,这样缩放完成之后就不会大于最大的宽度和高度

代码语言:javascript
复制
            var maxWidthScale = maxSize.Width / width;
            var maxHeightScale = maxSize.Height / height;

            var maxScale = Math.Min(maxWidthScale, maxHeightScale);

现在获取了 minScale 和 maxScale 需要根据这两个缩放计算最小的缩放

代码语言:javascript
复制
            var scale = Math.Min(minScale, maxScale);

为了让图片显示更锐利,这里让缩放是整数,使用整数可能略大于最大的宽度和高度

代码语言:javascript
复制
            scale = Math.Ceiling(scale);

所有代码

代码语言:javascript
复制
        /// <summary>
        /// 宽度和高度不小于最小大小,但是不大于最大大小,缩放使用等比缩放
        /// <para/>
        /// 规则:
        /// <para/>
        /// - 如果有一边小于最小大小,那么缩放到这一边大于等于最小大小
        /// <para/>
        /// - 如果一边缩放之后大于最大的大小,那么限制不能超过最大的大小
        /// <para/>
        /// - 尽可能让大小接近最小大小,但是保证宽度和高度都不大于最大大小
        /// </summary>
        /// <param name="currentSize"></param>
        /// <param name="minSize"></param>
        /// <param name="maxSize"></param>
        /// <returns></returns>
        static Size OptimizationSize(Size currentSize, Size minSize, Size maxSize)
        {
            if (currentSize.Width > minSize.Width && currentSize.Height > minSize.Height)
            {
                if (currentSize.Width <= maxSize.Width && currentSize.Height <= maxSize.Height)
                {
                    return currentSize;
                }
            }

            var height = currentSize.Height;
            var width = currentSize.Width;
            var widthScale = minSize.Width / width;
            var heightScale = minSize.Height / height;

            // 如果超过最大的大小
            var maxWidthScale = maxSize.Width / width;
            var maxHeightScale = maxSize.Height / height;

            var maxScale = Math.Min(maxWidthScale, maxHeightScale);
            var minScale = Math.Max(widthScale, heightScale);
            minScale = Math.Max(minScale, 1.0);
            var scale = Math.Min(minScale, maxScale);
            // 尽可能使用整数
            scale = Math.Ceiling(scale);
            return new Size(width * scale, height * scale);
        }

在 WPF 中可以通过设置 Image 控件的宽度和高度,此时因为尺寸是使用相同的值缩放,所以刚好图片使用 Fill 就能贴上去

但是无论用什么的算法,只要图片和原始尺寸不相同,那么一定会糊。无论是图片进行放大或缩小,都会模糊,这是基础的知识,想了解原理请自行百度

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
灰盒安全测试
腾讯知识图谱(Tencent Knowledge Graph,TKG)是一个集成图数据库、图计算引擎和图可视化分析的一站式平台。支持抽取和融合异构数据,支持千亿级节点关系的存储和计算,支持规则匹配、机器学习、图嵌入等图数据挖掘算法,拥有丰富的图数据渲染和展现的可视化方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档