I am using the desktop duplication api to grab the screen content and as it turns out, the new night light mode ('Nachtmodus' in German) is not applied in the grabbed screen content.
How do I read (if possible directly in c#) the night mode status (enabled, color shift amount)?
or
How can I tell Windows to give me the color shifted image using the desktop duplication api?
Basically, I want to know the state of what is configured inside these red boxes:
Background: I am working on an ambilight implementation and if the night light mode is enabled, the color shift is not reflected in the LEDs around my screen and so the colors are off between screen content and 'around screen'.
This method works for me in Windows 10 Version 2004
private static bool IsNightLightEnabled()
{
const string BlueLightReductionStateKey = #"SOFTWARE\Microsoft\Windows\CurrentVersion\CloudStore\Store\DefaultAccount\Current\default$windows.data.bluelightreduction.bluelightreductionstate\windows.data.bluelightreduction.bluelightreductionstate";
using (var key = Registry.CurrentUser.OpenSubKey(BlueLightReductionStateKey))
{
var data = key?.GetValue("Data");
if (data is null)
return false;
var byteData = (byte[])data;
return byteData.Length > 24 && byteData[23] == 0x10 && byteData[24] == 0x00;
}
}
You can check the output of
GetDeviceGammaRamp
Function from the Win API. Compare the output to Night Light ON and OFF and you should detect it.
Or you can try to monitor this Reg key for changes
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\CloudStore\Store\Cache\DefaultAccount\$$windows.data.bluelightreduction.settings\Current
I think I found the registry entry that reflects the current night light status.
[HKEY_CURRENT_USER\Control Panel\Quick Actions\Control Center\QuickActionsStateCapture]
"Toggles"="Toggles,...,Microsoft.QuickAction.BlueLightReduction:true,..."
Although it is not very reliable because I think it requires that this particular toggle should be visible...
Related
In my app I need to measure a camera data if the glasses are moving or not. I get the data with:
quaternions["x"] = Camera.main.transform.rotation.x;
quaternions["y"] = Camera.main.transform.rotation.y;
quaternions["z"] = Camera.main.transform.rotation.z;
quaternions["w"] = Camera.main.transform.rotation.w;
quaternions["tx"] = Camera.main.transform.position.x;
quaternions["ty"] = Camera.main.transform.position.y;
quaternions["tz"] = Camera.main.transform.position.z;
If I move the glasses, the app works fine. But if I leave the glasses on the table, then after 4 minutes the glasses disable display and the code returns last stored data. Even if the charge cable is plugged in. If I press enable button on the glasses, the display is on again and the data is also right.
Is there some possibility to prevent the glasses falling asleep?
According to comment of #Kay, the solution is adding the line:
Screen.sleepTimeout = SleepTimeout.NeverSleep;
NOTE: this solution works if you use MixedRealityToolkit-Unity because it needs:
using UnityEngine;
You can adjust the sleep settings using the Device Portal under System->Preference.
When on battery, go to sleep after
When plugged in, go to sleep after
I'm working on a small personal application that should read some text (2 sentences at most) from a really simple Android screenshot. The text is always the same size, same font, and in approx. the same location. The background is very plain, usually a few shades of 1 color (think like bright orange fading into a little darker orange). I'm trying to figure out what would be the best way (and most importantly, the fastest way) to do this.
My first attempt involved the IronOcr C# library, and to be fair, it worked quite well! But I've noticed a few issues with it:
It's not 100% accurate
Despite having a community/trial version, it sometimes throws exceptions telling you to get a license
It takes ~400ms to read a ~600x300 pixel image, which in the case of my simple image, I consider to be rather long
As strange as it sounds, I have a feeling that libraries like IronOcr and Tesseract may just be too advanced for my needs. To improve speeds I have even written a piece of code to "treshold" my image first, making it completely black and white.
My current IronOcr settings look like this:
ImageReader = new AdvancedOcr()
{
CleanBackgroundNoise = false,
EnhanceContrast = false,
EnhanceResolution = false,
Strategy = AdvancedOcr.OcrStrategy.Fast,
ColorSpace = AdvancedOcr.OcrColorSpace.GrayScale,
DetectWhiteTextOnDarkBackgrounds = true,
InputImageType = AdvancedOcr.InputTypes.Snippet,
RotateAndStraighten = false,
ReadBarCodes = false,
ColorDepth = 1
};
And I could totally live with the results I've been getting using IronOcr, but the licensing exceptions ruin it. I also don't have $399 USD to spend on a private hobby project that won't even leave my own PC :(
But my main goal with this question is to find a better, faster or more efficient way to do this. It doesn't necessarily have to be an existing library, I'd be more than willing to make my own kind of letter-detection code that would work (only?) for screenshots like mine if someone can point me in the right direction.
I have researched about this topic and the best solution which I could find is Azure cognitive services. You can use Computer vision API to read text from an image. Here is the complete document.
How fast does it have to be?
If you are using C# I recommend the Google Cloud Vision API. You pay per request but the first 1000 per month are free (check pricing here). However, it does require a web request but I find it to be very quick
using Google.Cloud.Vision.V1;
using System;
namespace GoogleCloudSamples
{
public class QuickStart
{
public static void Main(string[] args)
{
// Instantiates a client
var client = ImageAnnotatorClient.Create();
// Load the image file into memory
var image = Image.FromFile("wakeupcat.jpg");
// Performs label detection on the image file
var response = client.DetectText(image);
foreach (var annotation in response)
{
if (annotation.Description != null)
Console.WriteLine(annotation.Description);
}
}
}
}
I find it works well for pictures and scanned documents so it should work perfectly for your situation. The SDK is also available in other languages too like Java, Python, and Node
I'm pretty new to c#, I want to make a program that alerts me if I prefixed window sound volume become too high, for example, I have Spotify running in the background suddenly a high pitch sound then i get an alert, is this possible to do for in a low-level way that I can understand?
I already tried, an open source code that uses cscore, I did make some advancement but its way to advance for me to even keep going with that, this is where the source code I use:
Getting individual windows application current volume output level as visualized in audio Mixer
I made it, so it sends a message box with the window name that went to high on sound, but it only worked 1 time after the first time I didn't get any more message boxes, if I could just make it so it keeps sending message boxes would be perfect for me
Edit
I downloaded the source code of the program linked here, it's at the bottom of the link
I changed
var value = audioMeterInformation.GetPeakValue();
to something like 0.9
and added a messagebox around here:
using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>()) {
var value = audioMeterInformation.GetPeakValue();
if (value != 0) {
if (process != null) {
seenPids.Add(sessionid);
List<double> samples;
if (!sessionIdToAudioSamples.TryGetValue(sessionid, out samples)) {
samples = new List<double>();
sessionIdToAudioSamples[sessionid] = samples;
if(process.MainWindowTitle == "NAME OF MY WINDOW")
{
MessageBox.Show("true");
}
}
var val = audioMeterInformation.GetPeakValue();
samples.Add(val);
truncateSamples(samples);
I'm getting the message box, but just 1 time, if the high volume sound happens again it won't show the message box again, it just happens once per window.
DISCLAIMER
This question is somewhat similar to another on StackOverflow, C# - Capturing the Mouse cursor image - but with a slightly different requirement.
BACKGROUND
I am writing a scriptable automation client that scraps data from 3 legacy Win32 systems.
Two of these systems may indicate the presence of finished tasks via a change in cursor bitmap when the cursor is hovered over some specific areas. No other hints (color change, status message) are offered.
My own code is derived from the original post mentioned on the disclaimer.
REQUIREMENTS
While I an able to capture the cursor bitmaps by programatically moving the cursor to a specific coordinate and capturing it via CURSORINFO, the idea was to allow an interactive user to continue using the computer. As it is, the forced positioning disrupts the process.
QUESTION
Is there a way to capture the cursor bitmap by parametrized position (e.g., request the CURSORINFO as if the focus was in window W at coordinates X, Y)?
A solution fulfilling the specifics of this question was implemented using the information provided by Hans Passant, so all credit must go to him.
The current setup is as shown:
It runs on a machine with two displays. Not shown in the picture is a small application that is actually responsible for the event monitoring and data scraping - it runs minimized and unattended.
Solution
Obtain the Window handle for the application to be tested (in this case, I cycled through all processes returned by Process.GetProcesses():
IntPtr _probeHwnd;
var _procs = Process.GetProcesses();
foreach (var item in _procs)
{
if (item.MainWindowTitle == "WinApp#1")
{
_probeHwnd= item.MainWindowHandle;
break;
}
}
With the window handle for the target application, we are now able to craft specific messages and send to it via SendMessage.
In order to pass coordinates to SendMessage we need to serialize both X and Y coordinates into a single long value:
public int MakeLong(short lowPart, short highPart)
{
return (int)(((ushort)lowPart) | (uint)(highPart << 16));
}
Knowing the specific coordinates we want to probe (_probeX,_probeY), now we can issue a WM_NCHITTEST message:
SendMessage(_probeHwnd, WM_NCHITTEST, NULL, (LPARAM)MakeLong(_probeX, _probeY));
We need GetCursorInfo to obtain the Bitmap:
Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO();
Win32Stuff.GetCursorInfo(ci);
Check if the return flag from GetCursorInfo indicates that the cursor is showing (pco.flags == CURSOR_SHOWING):
Use CopyIcon in order to obtain a valid handle for the cursor bitmap:
IntPtr hicon = default(IntPtr);
hicon = Win32Stuff.CopyIcon(ci.hCursor);
Use GetIconInfo to extract the information from the handler:
Win32Stuff.ICONINFO icInfo = default(Win32Stuff.ICONINFO);
Win32Stuff.GetIconInfo(hicon, icInfo);
Use the System.Drawing.Icon class to obtain a manageable copy using Icon.FromHandle, passing the value returned by CopyIcon;
Icon ic = Icon.FromHandle(hicon);
Extract the bitmap via Icon.ToBitmap method.
Bitmap bmp = ic.ToBitmap();
Limitations
This solution was tested on two different OSes: Windows XP and Windows 8. It only worked on Windows XP. On Windows 8 the cursor would flicker and return to the 'correct' format immediately, and the the captured CURSORINFO reflected that.
The test point areas must be visible (i.e., application must not be minimized, and test points can't be under an overlapping window. Tested window may be partially overlapped, though - and it doesn't need to have focus.)
When WM_NCHITTEST is issued, the current physical cursor over WebApp changes to whatever cursor bitmap is set by the probed application. CURSORINFO contains the cursor bitmap set by the probed application, but the coordinates always indicate the 'physical' location.
I wanted to know, what would the coding be if I wanted to toggle mute/unmute of my microphone. I am making a program that can run in the background and pickup a keypress event and toggle mute/unmute of the mic. Any help with any of that coding would be very helpful. I am pretty new to C#, and this is just a really simple program I wanted to make. That is all it does, is it will listen for keypress of the spacebar, even when the program is in the background, then when the spacebar is pressed it will mute/unmute the mic.
Thank you for any and all help!
For Windows Vista and newer, you can no longer use the Media Control Interface, Microsoft has a new Core Audio API that you must access to interface with audio hardware in these newer operating systems.
Ray Molenkamp wrote a nice managed wrapper for interfacing with the Core Audio API here:
Vista Core Audio API Master Volume Control
Since I needed to be able to mute the microphone from XP, Vista and Windows 7 I wrote a little Windows Microphone Mute Library which uses Ray's library on the newer operating systems and parts of Gustavo Franco's MixerNative library for Windows XP and older.
You can download the source of a whole application which has muting the microphone, selecting it as a recording device, etc.
http://www.codeguru.com/csharp/csharp/cs_graphics/sound/article.php/c10931/
you can use MCI (Media Control Interface) to access mics and change their volume system wise. Check the code below it should be setting volume to 0 for all system microphones. Code is in c; check pinvoke for details on how to translate this code to c#
#include "mmsystem.h"
...
void MuteAllMics()
{
HMIXER hmx;
mixerOpen(&hmx, 0, 0, 0, 0);
// Get the line info for the wave in destination line
MIXERLINE mxl;
mxl.cbStruct = sizeof(mxl);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_COMPONENTTYPE);
// find the microphone source line connected to this wave in destination
DWORD cConnections = mxl.cConnections;
for (DWORD j=0; j<cConnections; j++)
{
mxl.dwSource = j;
mixerGetLineInfo((HMIXEROBJ)hmx, &mxl, MIXER_GETLINEINFOF_SOURCE);
if (MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE == mxl.dwComponentType)
{
// Find a volume control, if any, of the microphone line
LPMIXERCONTROL pmxctrl = (LPMIXERCONTROL)malloc(sizeof MIXERCONTROL);
MIXERLINECONTROLS mxlctrl =
{
sizeof mxlctrl,
mxl.dwLineID,
MIXERCONTROL_CONTROLTYPE_VOLUME,
1,
sizeof MIXERCONTROL,
pmxctrl
};
if (!mixerGetLineControls((HMIXEROBJ) hmx, &mxlctrl, MIXER_GETLINECONTROLSF_ONEBYTYPE))
{
DWORD cChannels = mxl.cChannels;
if (MIXERCONTROL_CONTROLF_UNIFORM & pmxctrl->fdwControl)
cChannels = 1;
LPMIXERCONTROLDETAILS_UNSIGNED pUnsigned = (LPMIXERCONTROLDETAILS_UNSIGNED)
malloc(cChannels * sizeof MIXERCONTROLDETAILS_UNSIGNED);
MIXERCONTROLDETAILS mxcd =
{
sizeof(mxcd),
pmxctrl->dwControlID,
cChannels,
(HWND)0,
sizeof MIXERCONTROLDETAILS_UNSIGNED,
(LPVOID) pUnsigned
};
mixerGetControlDetails((HMIXEROBJ)hmx, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
// Set the volume to the middle (for both channels as needed)
//pUnsigned[0].dwValue = pUnsigned[cChannels - 1].dwValue = (pmxctrl->Bounds.dwMinimum+pmxctrl->Bounds.dwMaximum)/2;
// Mute
pUnsigned[0].dwValue = pUnsigned[cChannels - 1].dwValue = 0;
mixerSetControlDetails((HMIXEROBJ)hmx, &mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
free(pmxctrl);
free(pUnsigned);
}
else
{
free(pmxctrl);
}
}
}
mixerClose(hmx);
}
here you can find more code on this topic
hope this helps, regards
I have several microphones in win7 and class WindowsMicrophoneMuteLibrary.CoreAudioMicMute is incorrect in this case.
so I change the code and works great because now his cup Whistle all microphones and not just in the last recognized by win7.
I am attaching the new class to put in place.
http://www.developpez.net/forums/d1145354/dotnet/langages/csharp/couper-micro-sous-win7/