WuxioLin 反锯齿算法(反走样算法,Xiaolin Wu Anti-aliasing algorithm) C# 代码实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、锯齿和反锯齿
  • 二、Xiaolin Wu 算法代码
    • 1.C#完整代码如下
    • 2.举例和测试
  • 总结


前言

笔者前几日自己写了个佳明手表表盘的的一个入门级App,模拟指针的。发现在个别角度,指针的锯齿非常拉胯啊,搞得手表不是很美观。准备研究一下直线的反锯齿算法。 试了试GPT,柴先生推荐了几个算法,最后给的是XiaolinWu 的反锯算法,但是因为GPT的一贯的随意性,代码虽然看着好像不错,但是运行不了。只好继续探索该算法的原理,否则它的代码我也看不懂,也改不了。经过一天的研究,终于搞出来了代码,并基本理解了反锯齿算法的核心思想。下面的讨论指的都是基于计算机图形处理范畴,除非特别说明。


一、锯齿和反锯齿

由于显示器的像素是有限集合,因此在分辨率不出特别高的前提下,画一条斜直线,就会出现锯齿现象。如图,下图是windows画图工具经过放大之后的样子:
在这里插入图片描述
可以看到很明显的锯齿,在某些角度,这个锯齿现象会更加明显。因此如何消除锯齿现象,在要求较高的场合是很重要的。那么,锯齿能消除吗?答案是否定的。为啥呢?因为,这个显示器的特点就是这样。因为它的像素不能很小,在理论上,这些锯齿就是客观存在的。那么就没有办法了吗?实际上计算机图形,只不过是一个示意图而已,因此如果它看起来锯齿消失了,或者变小了,就可以了。没有必要纠结,真正的消失。这也是反锯齿算法依赖的基础。反锯齿算法,就是利用直线和背景的合理混合,使得人眼在观看时,感觉锯齿变小了,甚至有消失的感觉。因此问题的核心,就是怎么实现。

二、Xiaolin Wu 算法代码

本文代码主要是参考了
Wu反走样算法介绍(简单易懂) -Xiaolin Wu’s Algorithm
该博客解释的比较清楚,并给出了伪代码。改代码只能处理 第一象限的小于四十五度的斜线,对水平直线和垂直直线以及其他象限的画线方法都没有处理,但是仍然具有一定的参考价值。为了实用,本文对代码进行了完善,下面代码给出了一个完整的解决方案。

另一个更加详细的解释请参考:
计算机图形学-反走样

1.C#完整代码如下

代码说明:
1、使用了 bitmap 用以完成画点的操作(C#GDI中居然没有画点的函数,只好用图形处理)
2、使用了 Color.FromArgb(alpha, pen_color) 函数实现和背景色彩的 blend(混合?) 运算
3、线段的画法都是从小到大完成的,并对不同斜率的线段,分别采用了不同的坐标。例如小于45度的线段,采用 x 轴从小到大的计算方法;而大于 45度的线段,采用y从小到大的方法。这样做的目的,是防止出现断点。
4、 代码中的Dx 和 Dy 用于匹配3 所说的情况,就是在选择相邻点时是选择横向还是纵向的点。
5、由于是逐个像素计算的,因此直接使用斜率作为累加步长(1*K, 省了了1)

private static void DrawXiaoLnWuLine(Bitmap bitmap ,Color pen_color, PointF p0, PointF p1)
        {
            PointF p;
            float dx, dy;
            var Dx = 0;
            var Dy = -1;

            if (p1.X < p0.X)
            {
                p = p0;
                p0 = p1;
                p1 = p;
            }
            dx = p1.X - p0.X;
            dy = p1.Y - p0.Y;
            
            if (dy < 0)
            {
                Dy = 1;
            }

            double k = (double)dy / dx, e;
            var V1 = p0.X;
            var V2 = p1.X;
            float val;
           
            if (Math.Abs( k )> 1)
            {
                
                Dx = -1;
                Dy = 0;
                if (p1.Y < p0.Y)
                {
                    p = p0;
                    p0 = p1;
                    p1 = p;
                    
                }
                dx = p1.X - p0.X;
                dy = p1.Y - p0.Y;

                if (dx < 0)
                {
                    Dx = 1;
                }
                k = (double)dx / dy;
                
                V1 = p0.Y;
                V2 = p1.Y;
                
            }
            p = p0;
            for (val = V1, e = 0; val < V2; val+=1f)
            {
   
                var alpha = (int)(Math.Abs(e) * 255);
                Color color = Color.FromArgb(alpha, pen_color);

                bitmap.SetPixel( (int)p.X,(int) p.Y, color);
                color = Color.FromArgb(255-alpha, pen_color);
                bitmap.SetPixel((int)p.X +Dx, (int)p.Y + Dy, color);
                e += k;
                if (Dy != 0)
                {
                    p.Y += (float)k;
                    p.X = val;
                }
                else
                {
                    p.X += (float)k;
                    p.Y = val;
                }
                e = e % 1;
            }
           
        }

2.举例和测试

测试代码:

           var sx = pbx_01.Width / 2;
            var sy = pbx_01.Height / 2;
            var mHandLen = (int)pbx_01.Width / 2 -4;
            var angle = Math.PI / 30 ;
            var ex = sx + mHandLen * Math.Cos(angle);
            var ey = sy - mHandLen * Math.Sin(angle);
            var g1 = pbx_01.CreateGraphics();
            pbx_01.BackColor = Color.White;
            g1.DrawLine(new Pen(Color.Green), sx, sy, (int)ex, (int)ey);

            Bitmap bitmap = new Bitmap(pbx_02.Width, pbx_02.Height);

            //SolidBrush brush = new SolidBrush(Color.FromArgb(128, 0, 0, 128));
            Graphics g2 = Graphics.FromImage(bitmap);
            g2.FillRectangle(Brushes.White, 0, 0, bitmap.Width, bitmap.Height);
            var p0 = new Point(sx, sy);
            var p1 = new Point((int)ex,(int) ey);
            DrawXiaoLnWuLine(bitmap, Color.Green, p1, p0);
            pbx_02.Image = bitmap;

该处使用的url网络请求的数据。
测试效果如下:
在这里插入图片描述
左面是普通画线的效果,右面是使用了XiaolinWu算法之后的效果,可以看出,线段的锯齿得到了较好的弱化。


总结

其实不是所有的线段都要使用这个算法,只有在角度较小或者较大时才比较明显,因此使用时可根据实际情况进行判断,否则效率太低。

MaraSun BJFWDQ
2012-04-27

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/14763.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

甘肃vr全景数字化展厅提高企业品牌认知度和销售效果

相比传统式展厅给观众们呈现的是静态的视觉体会&#xff0c;缺乏实时交互水平。而720VR全景虚拟展厅能够提供高度真实的展览体验&#xff0c;融合视、听、触等各种感官享受&#xff0c;带来颠覆的沉浸式体验。 即便社恐的你也能在虚拟现实的世界游刃有余&#xff0c;想看哪里点…

AD9208子卡设计资料: 2 路 2.6GSPS/3GSPS AD 采集、2 路 12.6G DA 回放、高性能时钟发生器HMC7044 -FMC 子卡模块

板卡概述 FMC123 是一款基于 FMC 标准规范&#xff0c;实现 2 路 14-bit、3GSPSADC 采集功能、2 路 16-bit 12.6GSPS 回放子卡模块。该模块遵循 VITA57.1 标准&#xff0c;可直接与 FPGA 载卡配合使用&#xff0c;板卡 ADC 器件采用 ADI 公司的 AD9208 芯片&#xff0c;&…

《中学科技》期刊简介及投稿邮箱

《中学科技》期刊简介及投稿邮箱 《中学科技》以传播科技知识、启迪智慧、培养才能为宗旨&#xff0c;提供电子技术、计算机、陆海空模型、数学、物理、化学、生物、天文等方面的科技活动资料&#xff0c;特别注意通过科学观察&#xff0c;实验和制作实践的途径&#xff0c;培…

CCGNet用于发现共晶材料中的coformer

共晶工程&#xff08;cocrystal engineering&#xff09;在制药&#xff0c;化学和材料领域有广泛应用。然而&#xff0c;如何有效选择coformer一直是一个挑战性课题。因此&#xff0c;作者开发了一个基于GNN的深度学习框架用于快速预测共晶的形成。为了从现有报告的6819个正样…

Java项目上线之云服务器环境篇(二)——Tomcat的安装与配置

Java项目上线之云服务器环境篇&#xff08;二&#xff09;——Tomcat的安装与配置 Tomcat的选择&#xff1a; 云服务器tomcat的选择最好与本机项目运行的tomcat版本号一致&#xff0c;避免一些不必要的问题。 配置步骤&#xff1a; 1、首先进入云服务器创建好放置tomcat的文件…

重大剧透:你不用ChatGPT,它砸你饭碗

早晨看到路透社报道&#xff0c;盖茨说&#xff0c;与其争论技术的未来&#xff0c;不如专注于如何更好地利用人工智能。 这可能是他对马斯克他们呼吁暂停AI研发6个月的一种回应吧。 有种古语说&#xff1a;天下大势&#xff0c;浩浩汤汤&#xff0c;顺之者昌&#xff0c;逆之者…

2023年Q1天猫空调品牌销量排行榜

如今&#xff0c;空调的普及水平较高&#xff0c;空调行业进入存量换新为主的发展阶段。 根据鲸参谋数据分析平台的相关数据显示&#xff0c;2023年Q1在天猫平台上&#xff0c;空调的销量将近100万件&#xff0c;销售额将近30亿&#xff0c;同时&#xff0c;空调产品的产品均价…

免费gpt-4-国内使用gpt-4

如何用上gpt-4 GPT-4尚未正式发布和公开&#xff0c;因此我们无法提供对GPT-4的具体使用方法。但是&#xff0c;可以从GPT-4的前一代——GPT-3的使用经验和GPT-4的预期功能来看&#xff0c;建议如下&#xff1a; 了解GPT-4的语言处理能力和适用场景&#xff1a;GPT-4预计将进一…

vue---组件逻辑复用方法:Mixin/HOC/Renderless组件

目录 1、Mixin 2、HOC 3、Renderless组件 下文通过表单校验来分别讲解Mixin/HOC/Renderless组件这三种方式。 1、Mixin 通过mixin将一个公用的validate函数同步到每一个组件中去 mixin使用详细介绍见&#xff1a;vue---mixin混入_maidu_xbd的博客-CSDN博客一个混入对象可…

SpringBoot实战(十六) 集成Hystrix

目录 一、简介1.Hystrix 的定义&#xff1f;2.Hystrix 的用处&#xff1f;3.Hystrix 的三种状态&#xff1f;4.Hystrix 解决什么问题&#xff1f;5.Hystrix 的设计原理&#xff1f;6.Hystrix 的实现原理&#xff1f; 二、集成 Hystrix1.Maven 依赖2.application.yml简易版&…

AutoGPT 安装指南,使用避坑要点

最近&#xff0c; AIGC 中最火的可能就当属于 AutoGPT 了吧&#xff0c;首先简单介绍一下AutoGPT 背景 AutoGPT 是基于 ChatGPT API 接口开发&#xff0c;项目首推 GPT-4 模型&#xff0c;但 OpenAI 账号 API 只有 gpt-3.5-turo 权限同样也可以使用。 项目在 github 上获取的…

【服务器数据恢复】重装系统导致分区无法访问的数据恢复案例

服务器数据恢复环境&#xff1a; 磁盘柜raid卡15块磁盘组建一组raid5磁盘阵列&#xff0c;划分2个lun&#xff1b; 上层操作系统划分若干分区&#xff0c;通过LVM扩容方式将其中一个分区加入到了root_lv中&#xff0c;其他分区格式化为XFS文件系统。 服务器故障&#xff1a; 为…

DFMEA 在车用燃料电池空压机设计中的应用

摘要&#xff1a; DFMEA在空压机研发中的应用 氢气具有资源丰富、热值高和无污染等特点&#xff0c;因而是燃料电池汽车最理想的二次能源。空压机作为燃料电池汽车的关键总成&#xff0c;掌握其核心部件的设计和制造技术非常必要。应用传统的设计方法进行相关零部件如空气轴承…

Reid之损失函数理论学习讲解

基于深度学习的Reid主要流程为输入图像-->CNN(提取特征)-->Global average pooling-->特征向量&#xff0c;将用这些特征来衡量图像的相似情况。并用这些特征进行检索&#xff0c;返回分类情况。 在训练网络的时候需要涉及损失函数&#xff0c;因此就引出了表征学习和…

2023年淮阴工学院五年一贯制专转本应用文写作考试大纲

2023年淮阴工学院五年一贯制专转本应用文写作考试大纲 一、考核对象 本课程的考核对象是五年一贯制高职专转本秘书学专业普通在校生考生。 二、考核目的 通过课堂教学&#xff0c;学生应当能够识记、理解和应用有关应用文写作的基本理论和基本技能。其中&#xff0c;识记指…

优秀简历的HR视角:怎样打造一份称心如意的简历?

简历的排版应该简洁工整&#xff0c;注重细节。需要注意对齐和标点符号的使用&#xff0c;因为在排版上的细节需要下很大功夫。除此之外&#xff0c;下面重点讲述几点简历内容需要注意的地方。 要点1&#xff1a;不相关的不要写。 尤其是与应聘岗位毫不相关的实习经历&#x…

默认成员函数之构造函数,构造函数的特点,创建,调用与对象创建的一语双关,默认构造函数等

内置类型与自定义类型 C当中的类型的话分为两类&#xff1a;一种就是内置类型/基本类型&#xff0c;就是c语言自带的那些类型基本类型&#xff0c;如int, char, double, 指针&#xff08;任何类型的指针&#xff0c;因为指针就是地址嘛&#xff09;等等&#xff1b;还有就是自…

docker和k8s基础介绍

一 Docker介绍 1.1 docker是什么 Docker 是一个开源项目&#xff0c; 诞生于 2013 年初&#xff0c;最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会&#xff0c;遵从了 Apache 2.0协议&#xff0c; 项目代码在…

FFmpeg PCM 编码 AAC

1. 概要说明与流程图 1.1 概要: 1) FFmpeg 已经废弃了 AV_SAMPLE_FMT_S16 格式 PCM 编码 AAC,也就是说如果使用 FFmpeg 自带的 AAC 编码器,必须做音频的重采样(重采样为:AV_SAMPLE_FMT_FLTP),否则AAC编码是失败的。 2) 传输 PCM 数据时,采取截取缓存机制,解决接收数据包…

【无人机】回波状态网络(ESN)在固定翼无人机非线性控制中的应用(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…