Czy ktoś wie, jak robić zrzut ekranu w Java (nie swój własny ekran, ale każde inne okno na pulpicie i oni nie koniecznie musi być aktywny okno ) w systemie Windows ? W tym podobnym temacie jest wiele wątków, ale jeszcze nie znalazłem odpowiedzi.Java - Window Obraz
Próbowałem używać JNA, ale utknąłem po kilku próbach. Na przykład ...
public class Main {
public static void main(String[] args) {
Main m = new Main();
List<WindowInfo> list = m.getWindows();
for (int i=0;i<list.size();i++)
{
WindowInfo info = list.get(i);
System.out.println(info.getTitle());
}
WindowInfo wi = list.get(0);
W32API.HDC hdcSrc = User32.instance.GetWindowDC(wi.getHwnd());
W32API.HDC hdcMemory = Gdi32.instance.CreateCompatibleDC(hdcSrc);
//W32API.HBITMAP hBitmapMemory = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, int width, int height);
int width = wi.getRect().right - wi.getRect().left;
int height = wi.getRect().bottom - wi.getRect().top;
W32API.HBITMAP hBitmapMemory = Gdi32.instance.CreateCompatibleBitmap(hdcSrc, width, height);
W32API.HANDLE hOld = Gdi32.instance.SelectObject(hdcMemory, hBitmapMemory);
Gdi32.instance.BitBlt(hdcMemory, 0, 0, width, height, hdcSrc, width+2, height+2, 0x00CC0020);
/* # now how do we convert to a BufferedImage??? */
// clean up
Gdi32.instance.SelectObject(hdcMemory, hOld);
Gdi32.instance.DeleteDC(hdcMemory);
Gdi32.instance.DeleteObject(hBitmapMemory);
User32.instance.ReleaseDC(wi.getHwnd(), hdcSrc);
}
/**
*
* @return
*/
private List<WindowInfo> getWindows() {
final List<WindowInfo> list = new ArrayList<WindowInfo>();
User32.instance.EnumWindows(new WndEnumProc() {
public boolean callback(int hWnd, int lParam) {
if (User32.instance.IsWindowVisible(hWnd)) {
RECT r = new RECT();
User32.instance.GetWindowRect(hWnd, r);
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
String title = Native.toString(buffer);
if (title!=null&&title.length()>0) {
list.add(new WindowInfo(hWnd, r, title));
}
}
return true;
}
}, 0);
Collections.sort(list, new Comparator<WindowInfo>() {
public int compare(WindowInfo o1, WindowInfo o2) {
int i1 = (o1.getTitle()!=null&&o1.getTitle().length()>0?o1.getTitle():" ").charAt(0);
int i2 = (o2.getTitle()!=null&&o2.getTitle().length()>0?o2.getTitle():" ").charAt(0);
return i1 - i2;
}
});
return list;
}
Próbowałem również równowartość "PrintWindow()" API ...
Graphics g = form.CreateGraphics(); Bitmap bmp = new Bitmap(form.Size.Width, form.Size.Height, g); Graphics memoryGraphics = Graphics.FromImage(bmp); IntPtr dc = memoryGraphics.GetHdc(); bool success = PrintWindow(form.Handle, dc, 0); memoryGraphics.ReleaseHdc(dc); // bmp now contains the screenshot
Czy muszę używać JNI lub jakiegokolwiek innego narzędzia?
góry dzięki ...
bardzo ładny ... świetna odpowiedź! dzięki! – rog8gm
hej, czy myślisz, że możesz wyjaśnić, jak działa klasa HDC? Spróbowałem zrobić smily program zanim mogłem pomieścić kilka przypadków HDC, a następnie przekonwertować je na obraz buforowy, zastanawiam się, gdzie przechowywane są informacje HDC. – user4090
To sprawia, że jest trochę szybciej: 'BufferedImage image = new BufferedImage (szerokość, wysokość, BufferedImage.TYPE_INT_RGB); MemoryImageSource source = new MemoryImageSource (szerokość, wysokość, buffer.getIntArray (0, szerokość * wysokość), 0, szerokość); image.getGraphics(). DrawImage (Toolkit.getDefaultToolkit(). CreateImage (źródło), 0, 0, null); ' – onkelv