在显示器的校正中常常会涉及Gamma值、白点坐标、色温、三原色、荧光剂色度值等参数。不同的gamma值会使显示器的亮度和颜色有较大差别。gamma值较小时亮调的等级差比较大,对表现亮度的颜色有利,反之,gamma值较大时对暗调的等级差拉的很大,对表现暗色有利。人的视觉对RGB三色信号的感觉大致成对数变化而不是线性变化,gamma校正正是为了克服这种非线性。gamma值的选取应该使整个亮度级别变化均匀。

notebook的背光控制是通过EC完成的,EC可以通过调节电源电压来实现LCD亮度调节。应用层如果要实现这个功能是通过显卡的RAMP值来实现的。C#中可以调用gdi32.dll提供的函数SetDeviceGammaRamp 和 GetDeviceGammaRamp来实现。但在操作之前要使用GetHdc()得到显卡的句柄。

[DllImport("gdi32.dll")]
        private unsafe static extern bool SetDeviceGammaRamp(Int32 hdc, void* ramp);

[DllImport("gdi32.dll")]
        public static extern int GetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);

private static bool initialized = false;
        private static Int32 hdc;

private static void InitializeClass()
        {
            if (initialized) return;
            hdc = Graphics.FromHwnd(IntPtr.Zero).GetHdc().ToInt32();
            initialized = true;
        }

public static unsafe bool SetBrightness(short brightness)
        {
            InitializeClass();
            if (brightness > 255) brightness = 255;
            if (brightness < 0) brightness = 0;

short* gArray = stackalloc short[3 * 256];
            short* idx = gArray;
            for (int j = 0; j < 3; j++)
            {
                for (int i = 0; i < 256; i++)
                {
                    int arrayVal = i * (brightness + 128);
                    if (arrayVal > 65535) { arrayVal = 65535; }
                    *idx = (short)arrayVal;
                    idx++;
                }
            }
            //For some reason, this always returns false?
            bool retVal = SetDeviceGammaRamp(hdc, gArray);
            //Memory allocated through stackalloc is automatically free'd by the CLR.
            return retVal;
        }

程序运行后确实可以调整背光,功能没问题。这里有两个问题:

一个是SetDeviceGammaRamp返回值总是false ,另一个是gArray的计算,为什么是arrayVal = i * (brightness + 128);?

另一个版本:

[DllImport("gdi32.dll")]
        public static extern int GetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);

[DllImport("gdi32.dll")]
        public static extern int SetDeviceGammaRamp(IntPtr hDC, ref RAMP lpRamp);

[DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hWnd);

private static RAMP s_ramp = new RAMP();

private static RAMP ramp = new RAMP();

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct RAMP
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public UInt16[] Red;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public UInt16[] Green;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
            public UInt16[] Blue;
        }

public static unsafe void SetGamma(int gamma)
        {
            InitializeClass();
            ramp.Red = new ushort[256];
            ramp.Green = new ushort[256];
            ramp.Blue = new ushort[256];

for (int i = 1; i < 256; i++)
            {
                // gamma 必须在3和44之间
                ramp.Red[i] = ramp.Green[i] = ramp.Blue[i] = (ushort)(Math.Min(65535, Math.Max(0, Math.Pow((i + 1) / 256.0, gamma * 0.1) * 65535 + 0.5)));
            }
            SetDeviceGammaRamp(GetDC(IntPtr.Zero), ref ramp);
           
        }

public static unsafe int GetBrightness()
        {       
           
            int gamma = 0;           
            s_ramp.Red = new ushort[256];
            s_ramp.Green = new ushort[256];
            s_ramp.Blue = new ushort[256];
            GetDeviceGammaRamp(GetDC(IntPtr.Zero), ref s_ramp);            
            return gamma;
        }

运行后会改变gamma的值而不是背光。两个版本看起来是ramp算法不同其他都一样。而ramp是一个3*256的矩阵 用来代表RGB的修正值。

使用using System.Management;空间提供的类和物件实现:

using System.Management;

static void SetBrightness(byte targetBrightness)
        {
            ManagementScope scope = new ManagementScope("root\\WMI");
            SelectQuery query = new SelectQuery("WmiMonitorBrightnessMethods");
            using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
            {
                using (ManagementObjectCollection objectCollection = searcher.Get())
                {
                    foreach (ManagementObject mObj in objectCollection)
                    {
                        mObj.InvokeMethod("WmiSetBrightness",
                            new Object[] { UInt32.MaxValue, targetBrightness });
                        break;
                    }
                }
            }
        }

编译时总是提示找不到   ManagementScope ,没办法执行。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sets a monitor's brightness value. Increasing the brightness value makes the display on the monitor brighter, and decreasing it makes the display dimmer.

Vista下如何用软件控制屏幕高层的API可以方便地控制屏幕的亮度、色温、对比度、显示区等。

#include "PhysicalMonitorEnumerationAPI.h"
#include "HighLevelMonitorConfigurationAPI.h"
#pragma comment(lib,"dxva2.lib")void FreePhysicalMonitor(DWORD npm, LPPHYSICAL_MONITOR ppm)
{DestroyPhysicalMonitors(npm, ppm);// Free the array.free(ppm);
}LPPHYSICAL_MONITOR GetPhysicalMonitor(DWORD *pnpm)
{HMONITOR hMon = NULL;hMon = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);LPPHYSICAL_MONITOR ppm = NULL;DWORD npm = 0;BOOL bRet = GetNumberOfPhysicalMonitorsFromHMONITOR(hMon, &npm);if (bRet) { ppm = (LPPHYSICAL_MONITOR)malloc(npm * sizeof(PHYSICAL_MONITOR));if (ppm) {bRet = GetPhysicalMonitorsFromHMONITOR(hMon, npm, ppm);if (!bRet) {FreePhysicalMonitor(npm, ppm);ppm = NULL;npm = 0;}}}*pnpm = npm;return  ppm;
}

返回的是PHYSICAL_MONITOR数组,以下示例只是使用了第一个PHYSICAL_MONITOR元素。

1、调整屏幕前我们可以看看显示器支持什么功能,Vista提供的API是GetMonitorCapabilities(在有些显示器上虽然GetMonitorCapabilities调用失败,但仍然可以调整亮度等;在有些显示器上,从GetMonitorCapabilities返回的值看可以支持某些功能,但实际又不能。这些都另当别论)。

LPPHYSICAL_MONITOR ppm = 0;
ppm = GetPhysicalMonitor();
if (ppm) {
DWORD nmc = 0, nct = 0;
GetMonitorCapabilities(ppm->hPhysicalMonitor, &nmc, &nct);
CString str = _T("");
if (nmc & MC_CAPS_BRIGHTNESS) {
str += _T("Support brightness control\n");
}
if (nmc & MC_CAPS_COLOR_TEMPERATURE) {
str += _T("Support color temperature\n");
}
if (nmc & MC_CAPS_CONTRAST) {
str += _T("Support contrast\n");
}
.........
if (str == _T(""))
str = _T("Support None");
MessageBox(str);
FreePhysicalMonitor(npm, ppm);
}

2、如何调整亮度
LPPHYSICAL_MONITOR ppm = 0;
DWORD npm = 0;
ppm = GetPhysicalMonitor(&npm);

//这一步可以得到ppm ,并且szPhysicalMonitorDescription中有显示器的描述。但ppm->hPhysicalMonitor一直是NULL.

//有人知道原因吗?帮忙留言告知下
if (ppm) {
DWORD nMin = 0, nCur = 0, nMax = 0;
GetMonitorBrightness(ppm->hPhysicalMonitor, &nMin, &nCur, &nMax);
CString str;
str.Format(_T("Min:%d, Cur:%d, Max:%d"), nMin, nCur, nMax);
MessageBox(str);
SetMonitorBrightness(ppm->hPhysicalMonitor, nMin);
Sleep(1000);
SetMonitorBrightness(ppm->hPhysicalMonitor, nMax);
Sleep(1000);
SetMonitorBrightness(ppm->hPhysicalMonitor, nCur);
Sleep(1000);
FreePhysicalMonitor(npm, ppm);
}

3、调色温

LPPHYSICAL_MONITOR ppm = 0;
DWORD npm = 0;
ppm = GetPhysicalMonitor(&npm);
if (ppm) {
SetMonitorRedGreenOrBlueGain(ppm->hPhysicalMonitor, MC_RED_GAIN, 50);
Sleep(500);
SetMonitorRedGreenOrBlueGain(ppm->hPhysicalMonitor, MC_GREEN_GAIN, 49);
Sleep(500);
SetMonitorRedGreenOrBlueGain(ppm->hPhysicalMonitor, MC_BLUE_GAIN, 52);
MessageBox(_T("Set color temperature => Done"));

FreePhysicalMonitor(npm, ppm);
}

4、调对比度

LPPHYSICAL_MONITOR ppm = 0;
DWORD npm = 0;
ppm = GetPhysicalMonitor(&npm);
if (ppm) {
DWORD nMin, nCur, nMax;
GetMonitorContrast(ppm->hPhysicalMonitor, &nMin, &nCur, &nMax);
CString str;
str.Format(_T("Min:%d, Cur:%d, Max:%d"), nMin, nCur, nMax);
MessageBox(str);
SetMonitorContrast(ppm->hPhysicalMonitor, nMin);
Sleep(1000);
SetMonitorContrast(ppm->hPhysicalMonitor, nMax);
Sleep(1000);
SetMonitorContrast(ppm->hPhysicalMonitor, nCur);
Sleep(1000);
FreePhysicalMonitor(npm, ppm);
}

5、查看显示器类型

LPPHYSICAL_MONITOR ppm = 0;
DWORD npm = 0;
ppm = GetPhysicalMonitor(&npm);
if (ppm) {
TCHAR *descs[] = {
_T("Shadow-mask cathode ray tube (CRT)"),
_T("Aperture-grill CRT"),
_T("Thin-film transistor (TFT) display"),
_T("Liquid crystal on silicon (LCOS) display"),
_T("Plasma display"),
_T("Organic light emitting diode (LED) display"),
_T("Electroluminescent display"),
_T("Microelectromechanical display"),
_T("Field emission device (FED) display")
};
MC_DISPLAY_TECHNOLOGY_TYPE dtt;
GetMonitorTechnologyType(ppm->hPhysicalMonitor, &dtt);
CString str;
str.Format(_T("Technology type: %s"), descs[(int)dtt]);
MessageBox(str);
FreePhysicalMonitor(npm, ppm);
}

6、恢复出厂设置

LPPHYSICAL_MONITOR ppm = 0;
DWORD npm = 0;
ppm = GetPhysicalMonitor(&npm);
if (ppm) {
RestoreMonitorFactoryDefaults(ppm->hPhysicalMonitor);
FreePhysicalMonitor(npm, ppm);
}

LCD背光控制 brightness control相关推荐

  1. linux蜂鸣器控制实验,【Linux公开课】蜂鸣器使用、LCD背光控制、触摸屏校准、GPIO操作...

    摘要为方便使用蜂鸣器,系统为蜂鸣器提供类似LED的操作接口,对应的操作文件是/sys/class/leds/beep/brightness.写入1使蜂鸣器鸣叫,写入0停止鸣叫- 8.12 蜂鸣器使用 ...

  2. linux 背光驱动程序,Linux驱动工程师成长之路 LCD背光控制RT9379B

    老大说了,下周新的手机要回来了,用的是400*800的屏,到时候就由我来调这个屏了.把屏的spec和背光的spec都给了我让我先看看. 以前分析了LCD(framebuffer)的驱动框架,但是对于背 ...

  3. android lcd 背光控制流程

    此文章是网上看到的,在MTK平台基础上的背光控制流程的分析.个人觉得写得比较详细,于是截取部分内容转载出来. 不过话说在前头,对于lcd而言,决定显示效果的有几个因素:pwm,gama(屏幕灰度),饱 ...

  4. lcd背光节能matlab代码,【技术分享】LCD背光驱动节电技术-LABC/CABC

    LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多的表现媒介.随着技术的增强,人类对视觉的要求不断提高,对图像的分辨率.色彩的要求也越来越高. 我们的手机 ...

  5. Android 功耗(19)---LCD背光驱动节电技术-LABC/CABC

    LCD背光驱动节电技术-LABC/CABC LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多的表现媒介.随着技术的增强,人类对视觉的要求不断提高,对图像 ...

  6. LCD背光驱动 --Backlight

    显示屏按其显示原理大致可分为CRT(显像管).LCD(液晶)及OLED三类,从市场应用看,手机中使用的显示屏主流是LCD,OLED只在翻盖机的小屏中占有少量份额,而CRT在手机中没有用到.       ...

  7. LCD背光驱动节电技术-LABC/CABC

    FROM:http://bbs.coolpad.com/thread-2716462-1-1.html LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多 ...

  8. 如何配置LCD背光和LED,调试方法

    LCD背光和LED配置文件 alps/custom/<proj name>lk/cust_leds.c alps/custom/<proj name>/kernel/leds/ ...

  9. [LED]如何配置LCD背光和LED,调试方法

    [LED]如何配置LCD背光和LED,调试方法 [DESCRIPTION] 如何配置LCD背光和LED,调试方法 [SOLUTION] LCD背光和LED配置文件 alps/custom/<pr ...

最新文章

  1. 批处理taskkill运行结束不掉程序以及停留问题
  2. mxnet加载resnet,进行预测
  3. ASP.NET 缓存与SQL Server结合使用
  4. boost::process::system相关的测试程序
  5. 趣谈设计模式 | 模板方法模式(Template Method):封装不变部分,扩展可变部分
  6. JavaScript调用ATL COM(二)
  7. 数据结构-王道-排序
  8. java 开发 加固态_搭建一个完整的Java开发环境
  9. 渲染怎么加hdri_关于渲染参数设置,伽马2.2你想要知道的一切!
  10. Centos7下安装DB2
  11. 【Java并发.3】对象的共享
  12. 127 MySQL权限管理
  13. [2018.10.20 T2] 面包
  14. 学习 canvas (二) 绘制图表
  15. 想做合格的产品经理,你需要这个证书
  16. 【我的新颖社区社交产品架构构思设想】
  17. 解决Pycharm绘图报错:Error: failed to send plot to http://127.0.0.1:63342
  18. AWS创建用户、角色、策略
  19. 如何提升 Java 技术
  20. WPF中给文本框TextBox设置提示文字

热门文章

  1. 身份证号提取年龄方法python_身字的意思、身的繁体字、身的笔顺笔画、身字部首和繁体字身的意思...
  2. 微机原理与接口技术课程设计——数字电压表的设计(含完整代码与实验连接图)
  3. Laravel-API实践教程
  4. 苹果7无线网怎么连接电脑连接服务器,苹果无线耳机可以连电脑吗_苹果无线耳机连接电脑的图文教程-win7之家...
  5. Java 朴素贝叶斯分类器、SVM(5行代码)实现乳腺癌分类
  6. 云电脑的四重守护,安全有谱
  7. Python数学建模系列(六):蒙特卡洛算法
  8. SUSE系统添加开机自启项
  9. 网络斗地主游戏的完整设计与实现(二)系统的核心技术路线
  10. 彻底解决C盘不够用的问题(Windows 10)