我们能否在Windows OS(7,8,10)上使用GammaRamp(SetDeviceGammaRamp)将屏幕变成灰度?
我需要这个来模拟电子墨水阅读器。
我正在使用此类来控制色温,并尝试实现使用以下因素将RGB图像转换为灰度的算法:红色* 0.2126;绿色* 0.7152;蓝色* 0.0722
我在article中对此进行了阅读。
结果不是纯灰度。我不明白SetDeviceGammaRamp设置的gammaramp数组到底在改变颜色,这就是为什么不能实现灰度算法的原因。有什么建议如何使用SetDeviceGammaRamp在此类中实现灰度转换?
public static class GammaRamp
{
[DllImport("gdi32.dll")]
private unsafe static extern bool SetDeviceGammaRamp(Int32 hdc, ushort* ramp);
[DllImport("gdi32")]
private unsafe static extern bool GetDeviceGammaRamp(Int32 hdc, ushort* ramp);
private static Int32 hdc;
public static unsafe void Set(int aBrightness, int aRed, int aGreen, int aBlue)
{
double red = 1, green = 1, blue = 1;
red = (double)aRed / (double)255;
green = (double)aGreen / (double)255;
blue = (double)aBlue / (double)255;
//Memory allocated through stackalloc is automatically free'd by the CLR.
ushort* rgbArray = stackalloc ushort[768]; //3 * 256
ushort* idx = rgbArray;
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < 256; i++)
{
double arrayVal = (double)(i * (aBrightness + 128));
if (arrayVal > 65535)
arrayVal = (double)65535;
if (j == 0) //red
arrayVal = arrayVal * red * 0.2126;
else if (j == 1) //green
arrayVal = arrayVal * green * 0.7152;
else //blue
arrayVal = arrayVal * blue * 0.0722;
*idx = (ushort)arrayVal;
idx++;
}
}
hdc = Graphics.FromHwnd(IntPtr.Zero).GetHdc().ToInt32();
SetDeviceGammaRamp(hdc, rgbArray);
}
}
如果无法使用我喜欢的GammaRamp,因为Win 7,8和10支持它,我将使用一个新功能,但仅适用于Windows 10
但是要从WPF应用程序控制此设置,我必须更改以下注册表项
计算机\ HKEY_CURRENT_USER \软件\ Microsoft \ ColorFiltering \ Active = 1
Computer \ HKEY_CURRENT_USER \ Software \ Microsoft \ ColorFiltering \ FilterType = 0
我可以轻松做到这一点,但是如何使Windows OS从注册表中刷新此新设置?这也是一个有用的答案。
最后,我会说我知道MagSetColorEffect winAPI,如果无法使用GammaRamp或其他选项,我将在Windows 7中使用它,但这是最后一个选项,因为它需要启用Aero。限制。
最佳答案
使用SetDeviceGammaRamp
之类的功能来制作灰度滤镜是不可能的,因为它们分别作用于每个颜色通道。 lpRamp
参数设置视频卡使用的LUT,以将像素强度(将其保存在屏幕截图中)映射到传输的强度(将其放置在VGA连接器中的引脚上)。这在很大程度上是旧版API,不会影响屏幕截图,远程桌面或与所有图形卡一起使用。
要制作灰度彩色滤光片,必须从每个颜色通道中获取数据,并将其混合在一起。 (可选)您可以应用加权功能,使生成的图像更准确地反映人的感知。
您可以使用通过MagSetFullscreenColorEffect
函数指定的比例因子(大多数运行Windows 8或更高版本的PC以及绝大多数Windows 7 PC上都可用)。我目前无法访问FCU机器,但是我怀疑设置中的新选项只是调用MagSetFullscreenColorEffect
。MagSetFullscreenColorEffect
采用颜色矩阵,它使您可以变换RGBX的四个空间。您可以了解变换矩阵on MSDN或many other places。 ColorMatrix Viewer(GitHub)是用于测试和调整这些颜色矩阵的出色工具。
有关如何为此目的使用MagSetFullscreenColorEffect
的示例,请参见以下示例。
C ++:
#include <magnification.h>
#pragma comment(lib, "magnification.lib")
float redScale = 0.2126f, greenScale = 0.7152f, blueScale = 0.0722f;
MAGCOLOREFFECT magEffectInvert =
{
{
{ redScale, redScale, redScale, 0.0f, 0.0f },
{ greenScale, greenScale, greenScale, 0.0f, 0.0f },
{ blueScale, blueScale, blueScale, 0.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }
}
};
MagInitialize();
if (!MagSetFullscreenColorEffect(&magEffectInvert))
{
std::cout << "Failed " << GetLastError() << std::endl;
}
system("pause");
MagUninitialize();
C#:
using System;
using System.Runtime.InteropServices;
namespace ManagedColorPlayground
{
using static NativeMethods;
class Program
{
static void Main(string[] args)
{
float redScale = 0.2126f, greenScale = 0.7152f, blueScale = 0.0722f;
var magEffectInvert = new MAGCOLOREFFECT {
transform = new [] {
redScale, redScale, redScale, 0.0f, 0.0f,
greenScale, greenScale, greenScale, 0.0f, 0.0f,
blueScale, blueScale, blueScale, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 1.0f
}
};
MagInitialize();
MagSetFullscreenColorEffect(ref magEffectInvert);
Console.ReadLine();
MagUninitialize();
}
}
static class NativeMethods
{
const string Magnification = "Magnification.dll";
[DllImport(Magnification, ExactSpelling = true, SetLastError = true)]
public static extern bool MagInitialize();
[DllImport(Magnification, ExactSpelling = true, SetLastError = true)]
public static extern bool MagUninitialize();
[DllImport(Magnification, ExactSpelling = true, SetLastError = true)]
public static extern bool MagSetFullscreenColorEffect(ref MAGCOLOREFFECT pEffect);
public struct MAGCOLOREFFECT
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 25)]
public float[] transform;
}
}
}
在
MagSetFullscreenColorEffect
之前:在
MagSetFullscreenColorEffect
之后:关于c# - 在Windows OS上以灰度模式切换屏幕,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47369358/