-
模拟技术中的Avago发布具备短路和过载检测功能的隔离放大器
2020-11-09 23:30:21Avago Technologies(安华高科技)近日宣布,推出具备短路和过载检测功能的高性价比新系列隔离放大器产品。采用光学隔离技术以及Sigma-Delta调制进行信号处理,Avago的ACPL-785J隔离放大器可以直接对电源转换器中的... -
一种运算放大器组成加法器的设计
2021-01-20 03:49:51运算放大器的电路结构有三种主要形式。一是单端输入、单端输出,斩波稳定式直流放大器等采取这种形式。二是差分输入、单端输出,大多数集成运算放大器采取这种形式。三是差分输入、差分输出,直流放大器和部分 -
放大器介绍
2020-05-29 15:45:14选择放大器的原则 要实现某个要求确定的放大电路,到底该选择晶体管、运放还是功能放大器呢?为了 陈述方便,我们先定义晶体管放大器为最低级,功能放大器为最高级。 任何一个运算放大器或者功能放大器,内部都以...资料来源于《你好,放大器》 ,需要该文档的可以留下邮箱。
选择放大器的原则
要实现某个要求确定的放大电路,到底该选择晶体管、运放还是功能放大器呢?为了 陈述方便,我们先定义晶体管放大器为最低级,功能放大器为最高级。任何一个运算放大器或者功能放大器,内部都以若干个晶体管为主组成,所以,要实 现某个放大电路,如果高级放大器能够实现,那么低级放大器也一定能够实现。
比如一个仪表放大器,用三个独立的运放加一些电阻就可以实现,虽然性能可能会差 点。如果你愿意,用好多个晶体管也可以自己搭出来,毕竟那些运放内部就是一堆晶体管 的集合。
但是,反过来是不成立的。用一些晶体管实现的某个放大电路,你可能找不到合适的 运放,或者合适的功能放大器来替换它们。
因此,实现同样的某个放大功能,用户可能面临多种选择。
选择放大器有以下原则可以遵循:
1) 没有一成不变的原则,所有选择都是因事而异、因时而异的。
2) 一般情况下,多数人选择的,或者大的芯片生产商提供的选择,是正确的。请初 学者特别注意,收集各大芯片生产商的应用手册、实验室电路,以及数据手册中 给出的应用实例,对迅速开展设计,是非常有效的。
3) 一般情况下,如果能够采用合适的高级放大器,就不要选用低级放大器。
4) 不要迷信。有人以全分立为荣——用晶体管实现超级复杂的电路,以彰显自己的 水平高;有人抨击分立元器件,以使用最新出品的高级功能放大器为荣,似乎自 己见识渊博。这些都不好。心态平和的,该用什么就用什么,是最为合适的。
全差分运放
它有差分输入脚 IN+和 IN-,差分输出脚 OUT+和 OUT-,除此之外还有一个输入脚,称之 为 VOCM。如图 1-3 所示,它们之间的关系如下:
式(1-4)很容易理解,与标准运放的差别仅在于全差分运放的输出也是差分的。即差分 输出值等于差分输入值乘以一个很大的开环增益𝐴uo。
式(1-5)是一个新概念,当你在 VOCM端接入一个电压,那么差分输出的两个端子的共 模电压(即两个差分输出信号的平均值)将等于你输入的 VOCM。这可以理解为,两个差分 输出端子,将围绕着输入的 VOCM 波动。这个功能将常用于输出电平的移位。
利用与标准放大器中式(1-1)到式(1-3)完全相同的分析方法,可以准确求解出输 出。但为了避免大家早早地厌烦,我们先休息一下,第 3 章会帮大家分析的。
为了区别这两种运放,2 入 1 出的可以称为标准运放,2 入 2 出的可以称为全差分运 放,当然,大多数人还是把标准运放直接称为运放。至此,有了标准运放和全差分运放,结合负反馈理论,已经完全可以应对几乎所有的 放大问题。几十年来,科学家和工程师们以标准运放和全差分运放为核心,设计并实践了 成千上万种电路,任何一本书都难以把它们囊括在内。
但是,生产商为了他们的利益,当然也是为了用户的方便,又开发出了很多种功能放 大器
功能放大器
如果某个以运放为核心的放大电路,非常常用,生产厂家就会考虑把这个放大电路 (包括运放和外围电阻)进一步集成,提供给用户。这就是功能放大器。比如我们要设计一个放大电路,实现 Uo=Ui1- Ui2。使用运放可以给出图 1-4(a)所示的 电路。但是,在实现过程中,用户可能遇到 4 个电阻不好匹配的问题,而这个电路又是很 常见的,于是集成电路生产商(比如 ADI 公司)就把这个电路集成在一个叫做 AD8276 的 集成电路中,这就是一种功能放大器,被称为差动放大器——Difference Amplifier。
当然,这一种放大器内部的电阻有像 AD8276 一样的,是 1:1 的,也有 1:10,1:5,1:2 的,型号也就不同。这取决于哪种电阻匹配是较为常见的。
这就是所有功能放大器诞生的基础:功能很常见,用户自己做没有厂家做得好。
功能放大器种类很多,常见的有以下几种:
仪表放大器
高阻差分输入,输出有单端的,也有差分的,增益一般可以用一个外部电阻,由用户 选择设定。常用于仪器仪表的最前端,和传感器直接接触。仪表放大器内部通常具有 2 个或者更多的运放,最典型的是 3 运放结构。其它的还有 2 运放结构、电流镜结构、飞电容结构等。
仪表放大器具有极高的共模抑制比——对信号的差值极为敏感而对共模量不敏感,还 有极高的输入阻抗。但是它的输入管脚有工作限制:第一不得悬空,第二不能承载太高的 电压。
图 1-5 左边是 ADI 公司生产的 AD8221 管脚图,可以看出它有两个输入端-IN 和+IN, 一个输出端 VOUT,2 脚和 3 脚之间需要用户连接一个电阻,以决定仪表放大器的电压增 益。图 1-5 右边电路中给出了 AD627 的电压增益公式,电阻 RG越小,增益越大。
图 1-5 右边电路中,电阻桥组成的传感器感知被测信息,产生 VDIFF,以电压差的形式 反映被测信息,AD627 的两个输入端有极高的输入阻抗,几乎不会从传感器侧取用电流, 因此传感器输出阻抗的变化不会带来额外的影响,保证 VOUT=VREF+GVDIFF。
差动放大器
由一个运放和若干个激光校准电阻对集成在一起的电路,而其中的电阻值选择均以容 易形成差动放大器为目的。多数如 AD8276 一般,包含 4 个激光校准的电阻,也有 5 电阻、6 电阻甚至更多电阻 的,主要用于信号减法(比如电流检出) 、精确增益、信号的差分转单端、电平移位等。
生产厂家提供各式各样的差动放大器,主要目的是给用户提供高质量运放和激光校准 电阻对的组合。用户更看重的是那几个精密匹配的电阻。
以图 1-6 所示的 AD8270 为例,可以看出它内部由两个独立的差动放大器组成,每个 差动放大器都有 7 个电阻,用户可以在芯片外部对它们进行合适的连接,以实现不同的功 能。图 1-6 仅是一种连接方式,作为一个 AD 转换器 AD7688 的前级驱动电路。
除此之外,如果你想实现一个单纯的减法电路 U15=U+IN-U-IN,可以把 1 脚、5 脚、6 脚 悬空。要实现 U15=0.5(U+IN-U-IN),可以把 4、5、6 脚都接地,1 脚和 15 脚接到一起。要实 现 U15=2(U+IN-U-IN),可以把 1 脚和 2 脚接在一起,3 脚 4 脚接在一起,5、6 脚接地。
此时你应该明白,AD8270 外围的 7 个电阻为什么选择这样的阻值了吧——众多的排 列组合,可以实现多种功能。
程控增益放大器
放大器的增益可以由用户通过数字信号设定,或者说可以用处理器程序实施设定,因 此叫 Programmable,可程控,或者叫 Digital Controlled Variable Gain Amplifier。通常缩写 为 PGA 或者 DVGA。程控增益放大器的增益设定,有多个管脚配合设定 2 进制增益的,也有通过数字通信 接口给放大器写入命令的。
主要用于被测信号幅度变化较大且不可事先预知的情况:程控增益放大器的输出经过 ADC 进入处理器中,处理器分析所得数据,如果发现信号变化范围太小,可以发出指令, 用程序增大 PGA 的增益,如果信号变化范围过大,可以用程序实现增益的缩减,最终使得 放大器处于随时可调的最佳增益状态。
ADI 公司生产的程控增益放大器主要分为两类:低频段的精确增益型,以及高频段 的。图 1-7 是低频段的 AD8231 和高频段的 AD8366。
低频段追求精确增益以及其他优秀的直流性能,AD8231 靠三根线实现 8 种增益 1 倍、2 倍、……128 倍,15μV 失调电压,G=1 时仅有 0.08%的增益误差。但是它的带宽只 有 2.7MHz。
AD8366 的-3dB 带宽可以达到 600MHz,平坦区可达 100MHz 以上。但是它的增益准 确度只有±0.25dB,约为 0.97~1.03,±3%的误差。 AD8366 的增益控制很灵活,可以单独控制 2 路中的一路,也可以同步控制;可以并 行控制,也可以用 SPI 实施串行控制。
AD8231 内部是一个可以改变增益的仪表放大器,因此它既是程控增益放大器,又是 仪表放大器。
压控增益放大器
放大器的增益由外部施加的电压 VG连续控制。ADI 公司称之为 Variable Gain Amplifier, VGA。有 dB 线性和 V/V 线性两种。有的是正控制——VG越大,增益越大;有 的是负控制——VG越大,增益越小。用途很广泛。其中一个主要应用是自动增益控制 AGC。有些芯片为此还内嵌了输出有 效值检测环节,以直流电压表征输出幅度,此电压如果回送到负控制的压控增益放大器的 VG脚,可以方便实现 AGC 功能——输入幅度大范围改变时,输出幅度几乎不变。录音笔 中一般都具备这种功能:距离说话者远也罢、近也罢,录下的声音大小几乎是一致的。
dB 线性:以 dB 为单位的放大器增益,与控制电压 VG成线性关系。即每相同的控制 电压增量,获得相同的以 dB 为单位的增益改变。此类用途更广,芯片种类也多。
V/V 线性:电压增益(倍数,即 V/V),与控制电压 VG成线性关系。即每相同的控制 电压增量,获得相同的增益倍数改变。
AD602 是一款应用较为广泛的独立双通道压控增益放大器。每个通道由压控衰减环 节、固定增益环节级联组成,差分输入的 C1HI 和 C1LO 作为控制电压 VG,可实现10dB~30dB 的 dB 线性,DC~35MHz 的压控增益放大。AD8367 功能更为强大,500MHz 内实现-2.5dB~42.5dB 的 dB 线性压控放大,且正、 负控制靠 MODE 脚设定,内嵌输出有效值检测。
隔离放大器
实现放大器输入信号与输出信号之间的电气隔离。实现方法有三类:变压器型、光电 耦合器型、电容型。ADI 的产品主要是变压器型。如图所示是 AD202,一款我念书时就存在并持续发售的隔离放大器。左边是信号输入 区域,右边是输出区域,两个区域是完全隔离的,仅能通过上部的信号变压器、下部的电 源变压器实现信号和能量的传递。两区域之间的隔离电压可以高达 2000V。
信号通路为:左侧有一个独立的运放(图中左上角),以及随后的调制环节,把低频信 号变成 25kHz 的调制信号,通过隔离变压器传递到右侧,随后解调输出。
为了实现隔离,还需要给信号输入侧提供单独的隔离电源。AD202 图中下部是能量传 递,由右侧给左侧提供电力。这为用户提供了方便。但是,这种电源即图中的±7.5V,一般 仅能提供微弱的电力。
需要特别注意的是,隔离放大器只能放大低频信号,像 AD202 只有 2kHz 的带宽。
-
模拟技术中的一种运算放大器组成加法器的设计
2020-10-23 00:58:41运算放大器的电路结构有三种主要形式。一是单端输入、单端输出,斩波稳定式直流放大器等采取这种形式。二是差分输入、单端输出,大多数集成运算放大器采取这种形式。三是差分输入、差分输出,直流放大器和部分 -
什么是运算放大器?运算放大器工作原理
2021-01-20 01:33:52由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放是以单芯片... -
模拟技术中的简述运算放大器增益误差设计
2020-10-22 17:01:51运算放大器(简称"运放")是具有很高放大倍数的电路单元。在实际电路中,通常结合...但是如果系统对于放大器的需求超出集成电路放大器的需求时,常常会利用分立式元件来实现这些特殊规格的运算放大器。 运算放大器是 -
模拟技术中的低漂移、宽带功率放大器
2020-11-07 12:36:03当输出阻抗为50欧,负载阻抗以50欧端接时,要获得10VP-P的振幅,输出放大器必须有20VP-P的输出振幅。如果是低频放大,可在OP放大器中加一个电压增强器即可达到要求。如果是宽带放大器,则须快速转换和大输出电流。... -
TI使用高压放大器简化您的BOM
2021-01-20 01:26:13由于运算放大器(运放)规格不同,...然而,仅仅因为放大器的电源电压为36V或40V并不意味着它只能用于高压电源。 图1:单电源低侧单向电流感测电路 高电压、多用途放大器 TI的高电压放大器选择具有宽共模范围、高 -
运算放大器
2019-04-19 10:17:51由于早期应用于模拟计算机中,用以实现数学运算,故得名"运算放大器"。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放...运算放大器(简称"运放")是具有很高放大倍数的电路单元。在实际电路中,通常结合反馈网络共同组成某种功能模块。它是一种带有特殊耦合电路及反馈的放大器。其输出信号可以是输入信号加、减或微分、积分等数学运算的结果。 由于早期应用于模拟计算机中,用以实现数学运算,故得名"运算放大器"。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放是以单芯片的形式存在。运放的种类繁多,广泛应用于电子行业当中。
运算放大器最早被设计出来的目的是将电压类比成数字,用来进行加、减、乘、除的运算,同时也成为实现模拟计算机(analog computer)的基本建构方块。然而,理想运算放大器的在电路系统设计上的用途却远超过加减乘除的计算。今日的运算放大器,无论是使用晶体管(transistor)或真空管(vacuum tube)、分立式(discrete)元件或集成电路(integrated circuits)元件,运算放大器的效能都已经逐渐接近理想运算放大器的要求。早期的运算放大器是使用真空管设计,当前则多半是集成电路式的元件。但是如果系统对于放大器的需求超出集成电路放大器的需求时,常常会利用分立式元件来实现这些特殊规格的运算放大器。
1960年代晚期,仙童半导体(Fairchild Semiconductor)推出了第一个被广泛使用的集成电路运算放大器,型号为***TL081CDR***,设计者则是鲍伯·韦勒(Bob Widlar)。但是709很快地被随后而来的新产品μA741取代,741有着更好的性能,更为稳定,也更容易使用。741运算放大器成了微电子工业发展历史上一个独一无二的象征,历经了数十年的演进仍然没有被取代,很多集成电路的制造商至今仍然在生产741。直到今天μA741仍然是各大学电子工程系中讲解运放原理的典型教材。 -
模拟技术中的解析运放式射频放大器
2020-10-22 14:56:01运放是运算放大器的简称。在实际电路中,通常结合反馈网络共同组成某种功能模块。由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”,此名称一直延续至今。运放是一个从功能的角度命名的电路... -
简述运算放大器增益误差设计
2021-01-20 03:43:41运算放大器(简称"运放")是具有很高放大倍数的电路单元。在实际电路中,通常结合...但是如果系统对于放大器的需求超出集成电路放大器的需求时,常常会利用分立式元件来实现这些特殊规格的运算放大器。 运算放大器是 -
低漂移、宽带功率放大器
2021-01-20 04:17:36当输出阻抗为50欧,负载阻抗以50欧端接时,要获得10VP-P的振幅,输出放大器必须有20VP-P的输出振幅。如果是低频放大,可在OP放大器中加一个电压增强器即可达到要求。如果是宽带放大器,则须快速转换和大输出电流。... -
模拟技术中的用于高阻抗电路的低失真、低噪声放大器
2020-11-07 15:21:35电路的功能 近年来,噪声及失真特性得到改进的低噪声放大器品种繁多,已无须用分立元件制作了。此外,也有为了使噪声减到最小而降低源极电阻,同时输入端的偏流IR又比通用OP放大器还大的OP放大器(如NE5534等)。... -
由OP放大器构成的12DB/OCT低通滤波器
2021-01-19 19:12:43相当于缓冲放大器的A部分,以往都采用射极输出器等电压输出电路,这里使用OP放大器,可以减少直流漂移。 电路工作原理 12DB/OCT巴特沃次滤波器电路的Q值必须为0.707才能获得平坦特性,并且对于C2来说,... -
用于高阻抗电路的低失真、低噪声放大器
2021-01-20 04:15:06电路的功能 近年来,噪声及失真特性得到改进的低噪声放大器品种繁多,已无须用分立元件制作了。此外,也有为了使噪声减到而降低源极电阻,同时输入端的偏流IR又比通用OP放大器还大的OP放大器(如NE5534等)。但是... -
158运算放大器数据手册
2019-02-24 11:38:16[1] 由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放是以... -
单片机与DSP中的由OP放大器构成的12DB/OCT低通滤波器
2020-11-07 08:52:10相当于缓冲放大器的A部分,以往都采用射极输出器等电压输出电路,这里使用OP放大器,可以减少直流漂移。 电路工作原理 12DB/OCT巴特沃次滤波器电路的Q值必须为0.707才能获得最平坦特性,并且对于C2来说,... -
高压放大器到底有什么作用
2021-01-20 01:27:13什么是高压放大器?它有什么作用?由于运算放大器(运放)规格...然而,仅仅因为放大器的电源电压为36V或40V并不意味着它只能用于高压电源。 高电压、多用途放大器 TI的高电压放大器选择具有宽共模范围、高感测能力 -
低噪声CMOS运算放大器发布
2021-01-19 16:09:55由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放是以单... -
TI关于运算放大器学习资料
2020-06-22 14:43:54运放是运算放大器的简称。在实际电路中,通常结合反馈网络共同组成某种功能模块。由于早期应用于模拟计算机中,用以实现数学运算,故得名“运算放大器”,此名称一直延续至今。运放是一个从功能的角度命名的电路单元... -
运算放大器参考设计.pdf
2019-08-15 17:27:06由于早期应用于模拟计算机中,用以实现数学运算,故得名"运算放大器"。运放是一个从功能的角度命名的电路单元,可以由分立的器件实现,也可以实现在半导体芯片当中。随着半导体技术的发展,大部分的运放是以单芯片... -
模拟技术中的一种低压低功耗衬底驱动轨至轨运算放大器设计方案
2020-11-02 22:00:43随着便携式电子产品和超深亚微米集成电路技术的不断发展,低电源电压低功耗设计已成为现代CMOS运算放大器的发展趋势。降低功耗最直接有效的方法是降低电源电压。然而电源电压的降低,使得运算放大器的共模输入范围及... -
高频小信号放大器设计
2010-07-01 11:27:23高频小信号放大器设计 1.课程设计目的 高频调谐放大器广泛应用于通信系统和其它...高频小信号放大器的功能是实现对微弱的高频信号进行不失真的放大,从信号所含频谱来看,输入信号频谱与放大后输出信号的频谱是相同的。 -
一种低压低功耗衬底驱动轨至轨运算放大器设计方案
2021-01-20 04:00:02随着便携式电子产品和超深亚微米集成电路技术的不断发展,低电源电压低功耗设计已成为现代CMOS运算放大器的发展趋势。降低功耗直接有效的方法是降低电源电压。然而电源电压的降低,使得运算放大器的共模输入范围及... -
MFC完成图片查看器的功能
2020-04-05 09:49:19MFC完成图片查看器的功能 预期目标: 1.打开同类型的位图,文件按顺序排列时可顺序打开下一张图像; 2.用鼠标滚轮完成图像的放大及缩小,且以鼠标所指的像素点为固定像素点; 3.显示图像的绝对像素坐标和相对像素...MFC完成图片查看器的功能
预期目标:
1.打开同类型的位图,文件按顺序排列时可顺序打开下一张图像;
2.用鼠标滚轮完成图像的放大及缩小,且以鼠标所指的像素点为固定像素点;
3.显示图像的绝对像素坐标和相对像素坐标,并且显示图像的放大比例。需要注意的点:
1.在放大的时候,会遇到图像上、下、左、右侧超出显示控件的情况,因此在放大的时候,需要判断图像边界位置。
2.在放大及缩小的时候要保证图像长宽同比变换,即保证图像不失真。
3.在找出图像绝对像素坐标和相对像素坐标时,要注意比例转换。
4.开始楼主敲得代码,在缩放图像时,总是出现闪屏的现象,后来才发现原因,不能直接在控件里放置图像,需要在缓存一 次,就解决闪屏现象。效果图如下:
话不多说,直接上代码!原创不易,转载请注明出处,谢谢~
水平有限,欢迎指正交流~~
void CImageViewDlg::OnSize(UINT nType, int cx, int cy) { if (m_listRect.GetCount() > 0) { CRect dlgNow; GetWindowRect(&dlgNow); POSITION pos = m_listRect.GetHeadPosition();//第一个保存的是对话框的Rect CRect dlgSaved; dlgSaved = m_listRect.GetNext(pos); ScreenToClient(dlgNow); float x = dlgNow.Width() * 1.0 / dlgSaved.Width();//根据当前和之前保存的对话框的宽高求比例 float y = dlgNow.Height() *1.0 / dlgSaved.Height(); ClientToScreen(dlgNow); CRect childSaved; CWnd* pWnd = GetWindow(GW_CHILD); while (pWnd) { childSaved = m_listRect.GetNext(pos);//依次获取子窗体的Rect childSaved.left = dlgNow.left + (childSaved.left - dlgSaved.left)*x;//根据比例调整控件上下左右距离对话框的距离 childSaved.right = dlgNow.right + (childSaved.right - dlgSaved.right)*x; childSaved.top = dlgNow.top + (childSaved.top - dlgSaved.top)*y; childSaved.bottom = dlgNow.bottom + (childSaved.bottom - dlgSaved.bottom)*y; ScreenToClient(childSaved); pWnd->MoveWindow(childSaved); pWnd = pWnd->GetNextWindow(); } CWnd *pwnd = GetDlgItem(IDC_Picture); pwnd->GetClientRect(&picRect); CDC *pDC = pwnd->GetDC(); pDC->SetStretchBltMode(COLORONCOLOR); Image.Destroy(); File_Open = Image.Load(FilePath); if (File_Open != 0) { File_Open = 2; return; } RectSize(Image, picRect, curRect, Image_scale); ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); } }
打开文件。
void CImageViewDlg::OnBnClickedOpenFile() { CString filter = L"所有文件(*.bmp,*.jpg,*.tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp|JPG(*.jpg)|*.jpg|GIF(*.gif)|TIFF(*.tiff)|*.tiff"; CFileDialog Ofile(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL); g_iZoom = 1; g_iRadio = 0.5; if (IDOK == Ofile.DoModal()) { FilePath = Ofile.GetPathName(); CString fEnt = Ofile.GetFileExt(); End_name = fEnt.MakeLower(); File_Folder = FilePath.Left(FilePath.GetLength() - End_name.GetLength() - 2); CString tmp_count = FilePath.Left(FilePath.GetLength() - End_name.GetLength() - 1); tmp_count = tmp_count.Right(1); count = _ttoi(tmp_count); CWnd* pWnd = GetDlgItem(IDC_Picture); CDC* pDC = pWnd->GetDC(); HDC hDC = pDC->m_hDC; pWnd->GetClientRect(&picRect); Image.Destroy(); Image.Load(FilePath); Image_Rat = (float)Image.GetWidth() / (float)Image.GetHeight(); RectSize(Image, picRect, curRect, Image_scale); ::SetStretchBltMode(hDC, HALFTONE); ::SetBrushOrgEx(hDC, 0, 0, NULL); ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); SetDlgItemText(IDC_Text1, FilePath); ReleaseDC(pDC); } // TODO: 在此添加控件通知处理程序代码 } void CImageViewDlg::OnBnClickedNextFile() { CString filter = L"所有文件(*.bmp,*.jpg,*.tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp|JPG(*.jpg)|*.jpg|GIF(*.gif)|TIFF(*.tiff)|*.tiff"; CFileDialog Ofile(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter, NULL); CString tmp_Path, tmp_count; g_iZoom = 1; g_iRadio = 0.5; count++; tmp_count.Format(_T("%01d."), count); FilePath = File_Folder + tmp_count + End_name; CWnd* pWnd; pWnd = GetDlgItem(IDC_Picture); CDC* pDC = pWnd->GetDC(); HDC hDC = pDC->m_hDC; pWnd->GetClientRect(&picRect); Image.Destroy(); File_Open = Image.Load(FilePath); if (File_Open != 0) { count--; tmp_count.Format(_T("%01d."), count); FilePath = File_Folder + tmp_count + End_name; File_Open = Image.Load(FilePath); File_Open = 2; return; } Image_Rat = (float)Image.GetWidth() / (float)Image.GetHeight(); RectSize(Image, picRect, curRect, Image_scale); ::SetStretchBltMode(hDC, HALFTONE); ::SetBrushOrgEx(hDC, 0, 0, NULL); ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); SetDlgItemText(IDC_Text1, FilePath); ReleaseDC(pDC); // TODO: 在此添加控件通知处理程序代码 }
缩放到边缘时,避免图像移出显示窗口。
void CImageViewDlg::RectSize(CImage &inputImage, CRect &inputRect, CRect &outputRect, float &imput_scale) { float in_x, in_y; in_x = inputRect.Width(); in_y = inputRect.Height(); float rows, cols; rows = inputImage.GetHeight(); cols = inputImage.GetWidth(); float rat = cols / rows; if (rows > in_y && cols < in_x) { imput_scale = rows / in_y; outputRect.left = (in_x - (in_y * rat)) / 2; outputRect.right = outputRect.left + (in_y * rat); outputRect.top = 0; outputRect.bottom = in_y; } else if (rows < in_y && cols >in_x) { imput_scale = cols / in_x; outputRect.left = 0; outputRect.right = in_x; outputRect.top = (in_y - (in_x / rat)) / 2; outputRect.bottom = outputRect.top + (in_x / rat); } else if (rows > in_y && cols > in_x) { if ((rows / in_y) >= (cols / in_x)) { imput_scale = rows / in_y; outputRect.left = (in_x - (in_y * rat)) / 2; outputRect.right = outputRect.left + (in_y * rat); outputRect.top = 0; outputRect.bottom = in_y; } else if ((rows / in_y) < (cols / in_x)) { imput_scale = cols / in_x; outputRect.left = 0; outputRect.right = in_x; outputRect.top = (in_y - (in_x / rat)) / 2; outputRect.bottom = outputRect.top + (in_x / rat); } } else if (rows < in_y && cols < in_x) { if ((in_y / rows) >= (in_x / cols)) { imput_scale = cols / in_x; outputRect.left = 0; outputRect.right = in_x; outputRect.top = (in_y - (in_x / rat)) / 2; outputRect.bottom = outputRect.top + (in_x / rat); } else if ((in_y / rows) < (in_x / cols)) { imput_scale = rows / in_y; outputRect.left = (in_x - (in_y * rat)) / 2; outputRect.right = outputRect.left + (in_y * rat); outputRect.top = 0; outputRect.bottom = in_y; } } }
鼠标滚轮事件。
BOOL CImageViewDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt) { GetDlgItem(IDC_Picture)->GetWindowRect(&picRect); CWnd *pwnd = GetDlgItem(IDC_Picture); CDC *pDC = pwnd->GetDC(); pDC->SetStretchBltMode(COLORONCOLOR); if (picRect.PtInRect(Win_Point)) { int w = Image.GetWidth(), h = Image.GetHeight(); if (zDelta > 0) { if (g_iZoom >= 30) { CString tmp_rat = _T("图像最大百分比"); SetDlgItemText(IDC_Text3, tmp_rat); ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); } double zoom = g_iZoom + g_iRadio; g_iZoom = zoom; ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); } else if (zDelta < 0) { double zoom = g_iZoom - g_iRadio; g_iZoom = zoom; if (g_iZoom <= 1) { g_iZoom = 1; ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); CString tmp_rat = _T("图像最小百分比"); SetDlgItemText(IDC_Text3, tmp_rat); g_iZoom = 1; return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); } ZoomImage(Image, picRect, curRect, g_iZoom, Image_scale); } } return CDialogEx::OnMouseWheel(nFlags, zDelta, pt); } void CImageViewDlg::OnLButtonDown(UINT nFlags, CPoint point) { if (curRect.Width()*(g_iZoom) < picRect.Width()) { tmp_curRect.left = (picRect.Width() - curRect.Width() * g_iZoom) / 2; tmp_curRect.right = tmp_curRect.left + curRect.Width() * g_iZoom; tmp_curRect.top = curRect.top; tmp_curRect.bottom = curRect.bottom; if (tmp_curRect.PtInRect(curPoint)) { LButtonDown = true; Down_Point.x = curPoint.x; Down_Point.y = curPoint.y; } } if (curRect.Width()*(g_iZoom) >= picRect.Width()) { tmp_curRect = picRect; if (tmp_curRect.PtInRect(Win_Point)) { LButtonDown = true; Down_Point = curPoint; } } return CDialogEx::OnLButtonDown(nFlags, point); } void CImageViewDlg::OnLButtonUp(UINT nFlags, CPoint point) { if (curRect.Width()*(g_iZoom) < picRect.Width()) { tmp_curRect.left = (picRect.Width() - curRect.Width() * g_iZoom) / 2; tmp_curRect.right = tmp_curRect.left + curRect.Width() * g_iZoom; tmp_curRect.top = curRect.top; tmp_curRect.bottom = curRect.bottom; if (tmp_curRect.PtInRect(curPoint)) { LButtonDown = false; } } else if (curRect.Width()*(g_iZoom) >= picRect.Width()) { tmp_curRect = picRect; if (tmp_curRect.PtInRect(Win_Point)) { LButtonDown = false; } } LButtonDown = false; return CDialogEx::OnLButtonUp(nFlags, point); }
图像选择显示区域
void CImageViewDlg::ZoomImage(CImage &input_Image, CRect &client_Rect, CRect &show_Rect, double &Zoom, float &input_scale) { m_isMove = false; GetDlgItem(IDC_Picture)->GetWindowRect(&picRect); CWnd *pwnd = GetDlgItem(IDC_Picture); CDC *pDC = pwnd->GetDC(); HDC hDC = pDC->m_hDC; pDC->SetStretchBltMode(COLORONCOLOR); pwnd->GetClientRect(&picRect); float Rows = input_Image.GetHeight(); float Cols = input_Image.GetWidth(); CString tmp_rat; CDC MemDC; CBitmap MemBitmap; MemDC.CreateCompatibleDC(NULL); MemBitmap.CreateCompatibleBitmap(pDC, picRect.Width(), picRect.Height()); MemDC.SelectObject(&MemBitmap); MemDC.FillSolidRect(0, 0, picRect.Width(), picRect.Height(), RGB(240, 240, 240));//填充初始颜色 MemDC.SetStretchBltMode(HALFTONE); ///HALFTONE if (curRect.Width() * Zoom < picRect.Width()) { show_Point.x = 0; show_Point.y = m_imagePoint.y - (((Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height())) * curPoint.y)/picRect.Height()); if (show_Point.y<0) { show_Point.y = 0; input_Image.Draw(MemDC.GetSafeHdc(), ((picRect.Width() - curRect.Width() * Zoom) / 2), picRect.top, (curRect.Width() * Zoom), picRect.Height(), show_Point.x, show_Point.y, Cols, (Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / Zoom) / ((curRect.Width() * Zoom) / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); tmp_Zoom = Zoom; move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.y + (Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height()))) > Rows) { show_Point.y = Rows - (Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height())); input_Image.Draw(MemDC.GetSafeHdc(), ((picRect.Width() - curRect.Width() * Zoom) / 2), picRect.top, (curRect.Width() * Zoom), picRect.Height(), show_Point.x, show_Point.y, Cols, (Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / Zoom) / ((curRect.Width() * Zoom) / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); tmp_Zoom = Zoom; move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), ((picRect.Width() - curRect.Width() * Zoom) / 2), picRect.top, (curRect.Width() * Zoom), picRect.Height(), show_Point.x, show_Point.y, Cols, (Cols / (((float)curRect.Width()*Zoom) / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); SRCCOPY tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / Zoom) / ((curRect.Width() * Zoom) / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); tmp_Zoom = Zoom; } else if (curRect.Width() * Zoom >= picRect.Width()) { show_Point.x = m_imagePoint.x - (int) ((float)(Cols * curPoint.x) / ((float)picRect.Width() *(Zoom - tmp_Zoom + 1))); show_Point.y = m_imagePoint.y - (int) ((float)(Cols * curPoint.y) / ((float)picRect.Width() *(Zoom - tmp_Zoom + 1))); if (show_Point.x <0) { show_Point.x = 0; if (show_Point.y < 0) 左上角一次判断 { show_Point.y = 0; input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); SRCCOPY tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.y + ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))) > Rows) /左下角一次判断 { show_Point.y = Rows - ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height())); input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); SRCCOPY tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); SRCCOPY tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if (show_Point.y < 0) { show_Point.y = 0; if (show_Point.x < 0) /左上角二次判断 { show_Point.x = 0; input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.x + (Cols / (Zoom - tmp_Zoom + 1))) > Cols) ///右上角一次判断 { show_Point.x = Cols - (Cols / (Zoom - tmp_Zoom + 1)); input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.x + (Cols / (Zoom - tmp_Zoom + 1))) > Cols) { show_Point.x = Cols - (Cols / (Zoom - tmp_Zoom + 1)); if (show_Point.y < 0) 右上角二次判断 { show_Point.y = 0; input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if((show_Point.y + ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))) > Rows) 右下角一次判断 { show_Point.y = Rows - ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height())); input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.y + ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))) > Rows) { show_Point.y = Rows - ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height())); if (show_Point.x < 0) { show_Point.x = 0; input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } if ((show_Point.x + (Cols / (Zoom - tmp_Zoom + 1))) > Cols) { show_Point.x = Cols - (Cols / (Zoom - tmp_Zoom + 1)); input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; return; } input_Image.Draw(MemDC.GetSafeHdc(), picRect.left, picRect.top, picRect.Width(), picRect.Height(), show_Point.x, show_Point.y, (Cols / (Zoom - tmp_Zoom + 1)), ((Cols / (Zoom - tmp_Zoom + 1)) / ((float)picRect.Width() / (float)picRect.Height()))); pDC->BitBlt(picRect.left, picRect.top, picRect.Width(), picRect.Height(), &MemDC, 0, 0, SRCCOPY); SRCCOPY tmp_rat.Format(_T("图像百分比: %d "), (int)(100 * picRect.Height() / ((Cols / (Zoom)) / ((float)picRect.Width() / (float)picRect.Height())))); SetDlgItemText(IDC_Text3, tmp_rat); } move_Point = show_Point; m_realPoint = show_Point; m_movePoint = show_Point; }
-
电子测量中的快速生成放大器TOI和其他IMD失真测量所需的音频信号
2020-12-08 12:35:42双音频和多音频信号被广泛应用于通信和国防领域,用以测试元器件、设备、子系统和系统内部生成的多余的、非线性频谱失真。互调失真(IMD)的产生与带内和带外的多余频谱信号有关,这些信号由两个或多个有用的频率成分...