LCD背光控制 brightness control
在显示器的校正中常常会涉及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相关推荐
- linux蜂鸣器控制实验,【Linux公开课】蜂鸣器使用、LCD背光控制、触摸屏校准、GPIO操作...
摘要为方便使用蜂鸣器,系统为蜂鸣器提供类似LED的操作接口,对应的操作文件是/sys/class/leds/beep/brightness.写入1使蜂鸣器鸣叫,写入0停止鸣叫- 8.12 蜂鸣器使用 ...
- linux 背光驱动程序,Linux驱动工程师成长之路 LCD背光控制RT9379B
老大说了,下周新的手机要回来了,用的是400*800的屏,到时候就由我来调这个屏了.把屏的spec和背光的spec都给了我让我先看看. 以前分析了LCD(framebuffer)的驱动框架,但是对于背 ...
- android lcd 背光控制流程
此文章是网上看到的,在MTK平台基础上的背光控制流程的分析.个人觉得写得比较详细,于是截取部分内容转载出来. 不过话说在前头,对于lcd而言,决定显示效果的有几个因素:pwm,gama(屏幕灰度),饱 ...
- lcd背光节能matlab代码,【技术分享】LCD背光驱动节电技术-LABC/CABC
LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多的表现媒介.随着技术的增强,人类对视觉的要求不断提高,对图像的分辨率.色彩的要求也越来越高. 我们的手机 ...
- Android 功耗(19)---LCD背光驱动节电技术-LABC/CABC
LCD背光驱动节电技术-LABC/CABC LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多的表现媒介.随着技术的增强,人类对视觉的要求不断提高,对图像 ...
- LCD背光驱动 --Backlight
显示屏按其显示原理大致可分为CRT(显像管).LCD(液晶)及OLED三类,从市场应用看,手机中使用的显示屏主流是LCD,OLED只在翻盖机的小屏中占有少量份额,而CRT在手机中没有用到. ...
- LCD背光驱动节电技术-LABC/CABC
FROM:http://bbs.coolpad.com/thread-2716462-1-1.html LCD背光驱动节电技术-LABC/CABC 图像永远是最直观的表现方式,而LCD正是目前应用最多 ...
- 如何配置LCD背光和LED,调试方法
LCD背光和LED配置文件 alps/custom/<proj name>lk/cust_leds.c alps/custom/<proj name>/kernel/leds/ ...
- [LED]如何配置LCD背光和LED,调试方法
[LED]如何配置LCD背光和LED,调试方法 [DESCRIPTION] 如何配置LCD背光和LED,调试方法 [SOLUTION] LCD背光和LED配置文件 alps/custom/<pr ...
最新文章
- 批处理taskkill运行结束不掉程序以及停留问题
- mxnet加载resnet,进行预测
- ASP.NET 缓存与SQL Server结合使用
- boost::process::system相关的测试程序
- 趣谈设计模式 | 模板方法模式(Template Method):封装不变部分,扩展可变部分
- JavaScript调用ATL COM(二)
- 数据结构-王道-排序
- java 开发 加固态_搭建一个完整的Java开发环境
- 渲染怎么加hdri_关于渲染参数设置,伽马2.2你想要知道的一切!
- Centos7下安装DB2
- 【Java并发.3】对象的共享
- 127 MySQL权限管理
- [2018.10.20 T2] 面包
- 学习 canvas (二) 绘制图表
- 想做合格的产品经理,你需要这个证书
- 【我的新颖社区社交产品架构构思设想】
- 解决Pycharm绘图报错:Error: failed to send plot to http://127.0.0.1:63342
- AWS创建用户、角色、策略
- 如何提升 Java 技术
- WPF中给文本框TextBox设置提示文字
热门文章
- 身份证号提取年龄方法python_身字的意思、身的繁体字、身的笔顺笔画、身字部首和繁体字身的意思...
- 微机原理与接口技术课程设计——数字电压表的设计(含完整代码与实验连接图)
- Laravel-API实践教程
- 苹果7无线网怎么连接电脑连接服务器,苹果无线耳机可以连电脑吗_苹果无线耳机连接电脑的图文教程-win7之家...
- Java 朴素贝叶斯分类器、SVM(5行代码)实现乳腺癌分类
- 云电脑的四重守护,安全有谱
- Python数学建模系列(六):蒙特卡洛算法
- SUSE系统添加开机自启项
- 网络斗地主游戏的完整设计与实现(二)系统的核心技术路线
- 彻底解决C盘不够用的问题(Windows 10)