Ok, sto cercando una funzione o qualcosa che leggerà il colore di un determinato pixel sul mio monitor, e quando verrà rilevato quel colore, verrà abilitata un'altra funzione. Immagino di usare RGB. Tutto l'aiuto è apprezzato. Grazie.Come leggere il colore di uno schermo Pixel
risposta
Per quanto ne so il modo più semplice per farlo è quello di:
- take a screenshot
- sguardo al bitmap e ottenere il colore del pixel
Modifica
Probabilmente non c'è modo di "aspettare" finché il pixel non cambia in un determinato colore. Probabilmente il tuo programma si limiterà a loopare e controllarlo ogni tanto fino a quando non vedrà il colore.
Ad esempio:
while(!IsPixelColor(x, y, color))
{
//probably best to add a sleep here so your program doesn't use too much CPU
}
DoAction();
EDIT 2
Ecco alcuni esempi di codice è possibile modificare. Questo codice cambia semplicemente il colore di un'etichetta in base al colore corrente in un dato pixel. Questo codice evita la perdita di handle menzionata.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
Thread t;
int x, y;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
x = 20;
y = 50;
t = new Thread(update);
t.Start();
}
private void update()
{
Bitmap screenCopy = new Bitmap(1, 1);
using (Graphics gdest = Graphics.FromImage(screenCopy))
{
while (true)
{
//g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(256, 256));
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
{
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
Color c = Color.FromArgb(screenCopy.GetPixel(0, 0).ToArgb());
label1.ForeColor = c;
}
}
}
}
}
Preferirei non farlo in questo modo, ci ho pensato ma non è un'opzione possibile. Il pixel deve essere guardato costantemente come troverà il pixel che sta cercando in meno di un minuto, costantemente. – Brandon
Quindi non dormire. Questo ciclo probabilmente impiegherebbe tutti i .1 secondi per scorrere nel peggiore dei casi. – tster
Nota che non si deve correre .CopyFromScreen, ha una perdita di maniglia, il migliore è quello di implementare questo codice da soli utilizzando API Win32 –
Questa è la più efficiente: Si prende un pixel nella posizione del cursore, e non si basa su un solo avere un monitor.
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
namespace FormTest
{
public partial class Form1 : Form
{
[DllImport("user32.dll")]
static extern bool GetCursorPos(ref Point lpPoint);
[DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);
public Form1()
{
InitializeComponent();
}
private void MouseMoveTimer_Tick(object sender, EventArgs e)
{
Point cursor = new Point();
GetCursorPos(ref cursor);
var c = GetColorAt(cursor);
this.BackColor = c;
if (c.R == c.G && c.G < 64 && c.B > 128)
{
MessageBox.Show("Blue");
}
}
Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
public Color GetColorAt(Point location)
{
using (Graphics gdest = Graphics.FromImage(screenPixel))
{
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
{
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, location.X, location.Y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
}
}
}
Ora, ovviamente, non è necessario utilizzare la posizione corrente del cursore, ma questa è l'idea generale.
EDIT:
Ciò premesso GetColorAt
funzione è possibile interrogare un certo pixel sullo schermo in una performance modo amichevole sicuro in questo modo:
private void PollPixel(Point location, Color color)
{
while(true)
{
var c = GetColorAt(location);
if (c.R == color.R && c.G == color.G && c.B == color.B)
{
DoAction();
return;
}
// By calling Thread.Sleep() without a parameter, we are signaling to the
// operating system that we only want to sleep long enough for other
// applications. As soon as the other apps yield their CPU time, we will
// regain control.
Thread.Sleep()
}
}
si può avvolgere che in un thread se vuoi, o eseguilo da un'applicazione Console. "Qualunque sia la tua fantasia," suppongo.
+1 per indicare che CopyFromScreen può essere usato per catturare solo una piccola area dello schermo. – tster
Ma nota che CopyFormScreen perde un handle ogni volta che lo chiami. –
Aggiornato per prevenire la perdita. –
prega di consultare questo due diverse funzioni che ho usato in uno dei miei progetti precedenti:
1) Questa funzione prende un'istantanea del desktop
private void CaptureScreenAndSave(string strSavePath)
{
//SetTitle("Capturing Screen...");
Bitmap bmpScreenshot;
Graphics gfxScreenshot;
bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);
MemoryStream msIn = new MemoryStream();
bmpScreenshot.Save(msIn, System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()[0], null);
msIn.Close();
byte[] buf = msIn.ToArray();
MemoryStream msOut = new MemoryStream();
msOut.Write(buf, 0, buf.Length);
msOut.Position = 0;
Bitmap bmpOut = new Bitmap(msOut);
try
{
bmpOut.Save(strSavePath, System.Drawing.Imaging.ImageFormat.Bmp);
//SetTitle("Capturing Screen Image Saved...");
}
catch (Exception exp)
{
}
finally
{
msOut.Close();
}
}
2) Questa funzione prende un'immagine in input e calcola Media RGB dell'intervallo di pixel indicato.
double GetRGBAverageForPixelRange(int istartRange, int iEndRange, Bitmap oBitmap)
{
double dRetnVal = 0 ;
Color oTempColor ;
int i, j ;
for(int iCounter = istartRange ; iCounter < iEndRange ; iCounter++)
{
i = (iCounter % (oBitmap.Width));
j = (iCounter/(oBitmap.Width)) ;
if (i >= 0 && j >= 0 && i < oBitmap.Width && j < oBitmap.Height)
{
oTempColor = oBitmap.GetPixel(i, j);
dRetnVal = dRetnVal + oTempColor.ToArgb();
}
}
return dRetnVal ;
}
Queste due funzioni potrebbero risolvere il problema. Happy Coding :)
EDIT: Si noti che GetPixel è una funzione molto lenta. Ci penserò due volte prima di usarlo.
La maggior parte delle risposte qui utilizza la stessa fonte di quel pixel (desktop dc).
La funzione del tasto è GetPixel
.
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetWindowDC(IntPtr window);
[DllImport("gdi32.dll", SetLastError = true)]
public static extern uint GetPixel(IntPtr dc, int x, int y);
[DllImport("user32.dll", SetLastError = true)]
public static extern int ReleaseDC(IntPtr window, IntPtr dc);
public static Color GetColorAt(int x, int y)
{
IntPtr desk = GetDesktopWindow();
IntPtr dc = GetWindowDC(desk);
int a = (int) GetPixel(dc, x, y);
ReleaseDC(desk, dc);
return Color.FromArgb(255, (a >> 0) & 0xff, (a >> 8) & 0xff, (a >> 16) & 0xff);
}
Penso che questo sia il modo più pulito e veloce.
Nota:
Se si è modificata la dimensione del testo di default tra le impostazioni di visualizzazione di Windows per aumentare la leggibilità su un display ad alta risoluzione, i parametri di GetPixel coordinata() devono essere regolati allo stesso modo. Ad esempio, se la posizione del cursore è (x, y) con il 150% della dimensione del testo su Windows 7, è necessario chiamare GetPixel (x * 1.5, y * 1.5) per ottenere il colore del pixel sotto il cursore.
Habib, la nota che hai aggiunto non fa parte della mia risposta. Non è il mio know-how, è tuo. Per favore, fai un commento, se puoi. Quindi puoi ottenere voti positivi sul commento. Inoltre penso che regolare xey su GetPixel sia fuori luogo. È meglio controllare le regolazioni della risoluzione e la posizione del cursore da qualche parte al di fuori del metodo GetColorAt. – Bitterblue
+1 per la nota sulla dimensione del testo sul display. Se c'è una dimensione del testo diversa da 100% e non è regolata correttamente, il metodo otterrà i colori dai pixel errati. –
- 1. Come leggere i pixel dello schermo?
- 2. iOS: rileva il colore di un pixel?
- 3. Matlab - come disegnare pixel su uno schermo intero nero?
- 4. Ottenere il colore del pixel in C++
- 5. Ottenere il colore dei pixel nella posizione con pygame
- 6. Come ottenere il colore dal pixel? OpenGL
- 7. Ottieni il colore più veloce dei pixel?
- 8. Come si legge un pixel fuori dallo schermo?
- 9. valore colore pixel rmagick
- 10. Come ottenere il colore di un pixel in un UIView?
- 11. Ottieni il colore dei pixel da un'immagine
- 12. Cambiare il colore dei pixel Python
- 13. Leggere in modo efficiente il colore medio del contenuto dello schermo reso da XBMC
- 14. Come definire la gamma chiara per il colore dei pixel
- 15. Mostra pixel sullo schermo in C
- 16. iOS WKWebView ottiene il colore del pixel RGBA dal punto
- 17. Come leggere il colore da un offset di LinearGradientBrush XAML?
- 18. Cambiare il colore di alcuni pixel in un UIImage
- 19. Ottieni il colore pixel di Base64 PNG usando javascript?
- 20. Cambiare il colore di uno StaticText, wxPython
- 21. Come acquisire una parte di uno schermo
- 22. Il colore gradiente CSS si arresta dalla fine in pixel
- 23. Come accedere al colore dei pixel all'interno di una bitmap?
- 24. Come posso leggere e scrivere dati JPEG su base pixel?
- 25. Leggere i pixel da una trama WebGL
- 26. Immagine WPF, modifica del colore dei pixel
- 27. Come fa il framment shader a sapere quale variabile usare per il colore di un pixel?
- 28. Android: come rilevare uno schermo e-ink?
- 29. Android: Ottieni la risoluzione dello schermo/pixel come valori interi
- 30. Come assegnare un nome per uno schermo?
Si desidera monitorare l'intero desktop o un'applicazione specifica per questo cambiamento di pixel? –
un certo pixel. Come dire il pixel a 125, 130 ho bisogno di aspettare fino a quando non rileva l'RGB di quel pixel andare a un certo RGB. – Brandon
Perché hai bisogno di fare questo? Sembra che ci sia una qualche ragione di fondo che se ci dai un po 'più di informazioni potremmo essere in grado di darti un modo migliore per ottenere la stessa cosa. Stai scrivendo un gioco e hai bisogno di determinare quando due oggetti si scontrano? Stai cercando di capire se un certo programma è iniziato? – Lee