AutoHotkey-GDIp: Capture a screenshot from a hardware accelerated window - screenshot

I am currently working on a small script which captures a screenshot from a hardware accelerated window in BlueStacks.
Problem is, that it appears the window must be hardware accelerated, so the screen capture is saving a black square.
I am using AutoHotkey for my scripting, and have added the GDIp libraries for access to GDI+.
I suspect the problem is that GDIp cannot grab the data using PrintWindow due to the software pushing the frame directly to the GPU, but there must be a way to capture this frame.
My script:
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
OnExit, Exit
#Include Gdip.ahk
#Include GDIpHelper.ahk
SetUpGDIP()
WinGet, hwnd, ID, BlueStacks App Player
pBitmap := Gdip_BitmapFromHWND(hwnd)
Gdip_SaveBitmapToFile(pBitmap, "TestOutput.png", 100)
Gdip_DisposeImage(pBitmap)
return
The actual screen to capture:
The actual file output by my script:
Any ideas on where to go or any kind of instruction on how to access the framebuffer perhaps? It can't be something no one has needed to do before.

I'm looking for a solution too. Anyway, I wrote it in another way:
pToken := Gdip_Startup()
winName := "BlueStacks App Player"
clientW := 868 ; set your client area width
clientH := 720 ; set your client area height
WinGetPos, x, y, w, h, %winName%
winBorder := (w-clientW)/2
x := x+winBorder
y := y+(h-clientH-winBorder)
snap := Gdip_BitmapFromScreen(x "|" y "|" clientW "|" clientH)
Gdip_SaveBitmapToFile(snap, "snap.png")
Gdip_DisposeImage(snap)
Gdip_ShutDown(pToken)
It's not elegant but works.
Probably there is an easy way to set clientW and clientH automaticly, but if your client area has fixed size (most cases) this is faster - no extra calculations.

Related

The function to calculate differential/derivative in DM

I remember that is a function to calculate the differential/derivative for a line plot in a DM version, it looks lik in the process- non linear filter- derivative. But I do not remember which version has this function, any suggestion?
The UI functionality for spectral filtering is found in the Spectrum menu:
Since GMS 3 this functionality is part oft the free software, before it was part of the Spectroscopy license (any).
The menu only works on line profiles which are spectra, for which the Convert Data To menu would be used when required.
As all "menu" commands, you can access them using the ChooseMenuItem command as in:
GetFrontImage().SelectImage() // Make sure the image window is selected, or the menu is disabled if the script-window is frontmost!
ChooseMenuItem("Spectrum","Numerical Filters","First derivative")
The mathematical functions behind this menu are also available as (unofficial, undocumented) script commands. They do not use the preferences but the parameters directly, using uncalibrated 'channel' scale.
So you could also use:
image src := GetFrontImage()
number chWidth = 5 // The values matching the settings
number chDelta = 1 // The values matching the settings
number chShift = trunc((chWidth + chDelta)/2 + 0.5)
number norm = chWidth + chDelta
image fDev := src.FDeriv_Spectrum( chWidth, chShift, norm )
fDev.ShowImage()
Just be warned that there is no guarantee that the command FDeriv_Spectrum will be continued in future versions of GMS (It is not an officially supported command.)
Finally, the math of a first derivative are really simple, so you could just recreate the function with pure DM-script commands like offset and arithmetic operators.
A simple, non-smoothed 1-channel derivative would simply be:
image src := GetFrontImage()
image fdev := src - src.offset(-1,0)
fdev.ShowImage()

Lua (CC) GUI class draws all components in the same window when told to draw them in separate windows

Prelude
ComputerCraft is a mod for Minecraft (Forge) that adds a crude lua-based Computer to the game. Using this Computer, one can write programs to interact with the Minecraft world in various ways. Whether a ComputerCraft question is applicable to StackOverflow has been previously debated in other questions, but I believe it is applicable, as the mod is, for the most part, about programming, and while some ComputerCraft proprietary API calls are made, there is no concept in this question that would not apply to other, non-ComputerCraft-related lua programs (unless of course the problem is caused by a bug in ComputerCraft itself). Documentation for the used APIs can be found at http://www.computercraft.info/wiki/Category:APIs.
Note: Do not be alarmed if you have no ComputerCraft experience; I believe that this issue may be completely unrelated to ComputerCraft, and instead be caused by some intricacy of OOP in lua that I have failed to grasp. I have commented the code where I felt it necessary to explain the most important aspects of the proprietary calls I am making. If anything is unclear, please comment and I will clarify.
If you want to be able to run the code examples without Minecraft, there is an excellent ComputerCraft emulator available called CCEmuRedux. I have tested my code on both actual ComputerCraft and CCEmuRedux with identical results, although CCEmuRedux doesn't seem to support Monitors. An "Advanced" Computer is necessary to see the colours.
Problem
In ComputerCraft 1.75 (and CCEmuRedux # ComputerCraft 1.79), given the following class gui, and a test program that attempts to draw a rudimentary button in each of two different windows using the gui class, both buttons are drawn in the second window. Graphically, the result of guiTest.lua is https://i.imgur.com/llFDlYI.png, while I would expect the first (orange) button to be drawn in Window 1. While I have some theories as to why it behaves this way, I don't have the necessary lua experience to figure out how to fix it. This is an MWE.
Code example
gui.lua
--Meta class
gui = {t, vpx, vpy}
function gui:new(t, title) -- I'm aware this constructor is not in keeping with the referenced Tutorialspoint article, it is of no consequence in this example
local o = o or {}
setmetatable(o, self)
self.__index = self
self.t = t
local sX, sY = self.t.getSize() -- get the size of the virtual terminal and save it to vpx, vpy
self.vpx = sX
self.vpy = sY
self.t.setCursorPos(1, 1) -- put cursor at the start of the virtual terminal
self.t.write(tostring(title)) -- note that this WORKS, it prints one title per Window as seen in the screenshot
return o
end
function gui:drawButton(x, y, sX, sY, colour)
self.t.setCursorPos(x, y) -- set the cursor to the button's first x- and y-coords
self.t.setTextColor(colours.black) -- set text colour to black
self.t.setBackgroundColor(colour) -- set background colour to the colour of the button
for iY = 1, sY do
for iX = 1, sX do
self.t.write("#") -- print hashtags to represent the button until we reach sX and sY
end
self.t.setCursorPos(x, y + iY) -- move cursor a line down, and back to button's first x-coord
end
self.t.setCursorPos(self.vpx, self.vpy) -- get cursor out of the way so the screenshot will be prettier
end
guiTest.lua
dofile('gui.lua')
local w1 = window.create(term.current(), 2, 2, 22, 15)
local w2 = window.create(term.current(), 26, 2, 22, 15) -- creates virtual windows in a terminal, acting as terminals of their own
-- window.create() arguments: terminal object to create window on, x position, y position, x size, y size
local g1 = gui:new(w1, "Window 1") -- create gui object for the first window
local g2 = gui:new(w2, "Window 2") -- create gui object for the second window
g1:drawButton(5, 3, 3, 2, colours.orange) -- should draw in w1, draws in w2
g2:drawButton(10, 8, 4, 4, colours.green) -- should draw in w2, draws in w2
Attempted solutions
For what it's worth, I've been following the Lua OOP recipe # https://www.tutorialspoint.com/lua/lua_object_oriented.htm. This is my second lua-based program, so I expect it to be an "easy" problem. I have more than a basic understanding of how OOP works in several other languages (particularly Java), though, and as such my programmer's "Spidey-Sense" is telling me that either some variable, such as t, isn't "local enough" (same variable gets used by both windows), or some reference in one of the gui objects gets overwritten when a new gui object gets created.
Therefore, I tried making the table gui local, to ensure it was not being overwritten:
local gui = {t, vpx, vpy}
... but it spat an error attempt to index ? on line 6 of "gui.lua" (setmetatable(o, self)), so instead I tried (realising that I would be unable to access the function from outside gui.lua, due to it being local):
local function gui:drawButton(x, y, sX, sY, colour)
... which resulted in guiTest.lua:1: bios.lua:14 [string "gui.lua"]:17:'(' expected. Line 17 is the definition of gui:drawButton() in the code tag above. In my admittedly limited ComputerCraft experience, such poorly formatted error messages generally mean that the lua interpreter or CraftOS is Exceptionally Confused™, but I assume the gist of it is "you can't make an object method local", as I can make other functions local in a similar fashion to what I've tried here.
It is not a problem with window.create() or with using the window API in general, as the same thing happens when using separate Monitors instead of just separate windows on the same Monitor. Essentially:
dofile('gui.lua')
local w = window.create(term.current(), 2, 2, 22, 15)
local m = peripheral.wrap('top') -- m becomes the Monitor physically on top of the ComputerCraft Computer
local gw = gui:new(w, "Window") -- create gui object for the Window
-- m is a terminal object, just like w, so we can still do
local gm = gui:new(m, "Monitor") -- create gui object for the Monitor
gw:drawButton(5, 3, 3, 2, colours.orange) -- should draw in w, draws in m
gm:drawButton(10, 8, 4, 6, colours.green) -- should draw in m, draws in m
Perhaps there is a way of storing the function as a local variable, along the lines of
local gui:printFoo = function() print("foo") end
self:printFoo() -- prints "foo"...?
... or perhaps more likely, the issue is something I have entirely missed.
Conclusion
To make a long question short, defining two gui objects, one for each of two virtual console windows, and attempting to draw one button on each of the virtual console windows using their respective gui objects, results in both buttons being drawn on the same virtual console window. Why?
Yes, OOP in Lua is hard for Lua beginners, despite of excellent knowledge of OOP languages (such as Java).
--Meta class
gui = {} -- class is a global variable, no default properties exist
function gui:new(t, title) -- t = window, self = your class "gui"
local o = {} -- creating NEW object
setmetatable(o, self) -- link the object with the class
self.__index = self
o.t = t -- save window into object (not into class)
local sX, sY = t.getSize() -- get the size of the virtual terminal
o.vpx = sX -- save window's properties into object (not into class)
o.vpy = sY
t.setCursorPos(1, 1)
t.write(tostring(title))
return o
end
function gui:drawButton(x, y, sX, sY, colour) -- self = object
....
end

clock pulse generator for a PLC

I am working with PLCs trying to design a water tank. On one section of the design I am asked to create a clock pulse generator. I am currently trying to do this using ladder diagrams.
I believe I have the logic correct just cant seem to put it together. I want a counter to count the clock pulses that I generate, then I store these pulese in a data memory to ensure the count is retained if the system is switched off and on.
question is how do I design this clock pulse generator.
Kind regards
There are a few different ways to create a pulse generator (or commonly known in the plc world as a BLINK timer). As a matter of fact many plc programming softwares have this function block built in to their function block libraries. But if they don't or you just want to make your own you can do something like this
VAR
ton1: TON;
ton2: TON;
StartPulse: BOOL;
startPulseTrig: R_TRIG;
LatchPulseInitial: BOOL;
PulseOutput: BOOL;
Timer1Done: BOOL;
Timer2Done: BOOL;
PulseWidth:TIME:=t#500ms;
END_VAR
If you would like to count the number of pulses and store this value to a variable you can use a simple CTU (counter up) block available in all plc languages.
Review of functionality
The StartPulse variable can be anything you want that will start the counter. In my case I just used an internal bool variable that I turned on. If you want this timer to start automatically when the plc starts then just initialize this variable to true. Because StartPulse only works on the rising edge of the signal the LatchPulseInitial coil will only ever be set once.
When the LatchPulseInitial variable goes true this will start ton1 a Timer On Delay (TON) function block. This will delay the output of the block from turning on for the time of PT (in my case I have 500ms).
After 500ms has expired the ton1 outputs will turn on. this will turn on the Timer1Done variable and turn off the Timer2Done and LatchPulseInitial. Now that LatchPulseInitial has been turned off it will never interfere with the program again since it can only be turned on by the rising edge of StartPulse. Note: once the block has reached PT the outputs will stay on until the input to the block is removed.
Since Timer1Done is now on ton2 will start counting until PT is reached. Once PT is reached the outputs for that block will turn on. This will reset Timer1Done and set Timer2Done This will start ton1 again and thus starting the whole process over.
For the PulseOutput, which is the actual pulse output you are looking for, I have this being set to true when Timer2Done is true. This is because when this variable is true it is the high state of the pulse generator. When Timer1Done is true it is the low state of the pulse generator.
When the PulseOutput goes true it will trigger the input on the CTU which will increment the count of the variable in CV (current value) by 1.
If you are going to be using this logic in numerous places in your program or you plan on reusing it in the future I would make this into its own function block so you won't have to repeat this logic everytime you want to make this type of timer.
Once I had to create a BLINK FB. It is written in Structured Text. But it is suitable to use in a ladder logic program and IN/OUT Variables are named like TON style. The Blink starts with Q = TRUE. If you want to start with FALSE just invert Q and switch the Times!
FUNCTION_BLOCK BLINK
VAR_INPUT
IN : BOOL;
PT_ON : TIME;
PT_OFF : TIME;
END_VAR
VAR_OUTPUT
Q : BOOL;
ET : TIME;
END_VAR
VAR
rtIN : R_TRIG;
tonBlink : TON;
END_VAR
rtIN(CLK := IN);
IF tonBlink.Q OR rtIN.Q THEN
(*Toggle Output*)
Q := NOT Q;
(*Timer Reset call, important to call timer twice in same cycle for correct Blink Time*)
tonBlink(IN:= FALSE);
(*Set corresponding Time*)
IF Q THEN
tonBlink.PT := PT_ON;
ELSE
tonBlink.PT := PT_OFF;
END_IF
END_IF
(*Timer Run call*)
tonBlink(IN:= IN);
IF IN THEN
ET := tonBlink.ET;
ELSE
ET := T#0S;
Q := FALSE;
END_IF
In my opinion, this is the most straightforward way to do it, using 1 timer, up counter and modulo operator:
Blink function in ladder
Also note, if your PLC doesnt have modulo, then multiply by -1 each time.

Arduino + OV7670 - Without FIFO - Reading Snapshot

I know that there is a lot in internet (http://forum.arduino.cc/index.php?topic=159557.0 for example) about OV7670 and I read a lot about it, but seems something is missing.
First of all I took a look into the way how can we read pixel by pixel from the camera to build the rectangular 600 X 480 image, and this was quite easy to understand considering HREF, VSYNCH and PCLOCK described on documentation here: http://www.voti.nl/docs/OV7670.pdf. I understand XCLOCK as an input I need to give to OV7670 as a kind of cycle controller and RESET would be something to reset it.
So at this point I thought that the functionality of such camera would be covered by wiring the following pins:
D0..D7 - for data (pixel) connected to arduino digital pins 0 to 7 as INPUT on arduino board
XCLK - for camera clock connected to arduino digital pin 8 as OUTPUT from arduino board
PCLK - for pixel clock connected to arduino digital pin 9 as INPUT on arduino board
HREF - to define when a line starts / ends connected to arduino digital pin 10 as INPUT on arduino board
VSYCH - to define when a frame starts / ends connected to arduino digital pin 11 as INPUT on arduino board
GRD - groud connected to arduino GRD
3V3 - 3,3 INPUT connected to arduino 3,3v
RESET - connected to arduino RESET
PWDN - connected to arduino GRD
The implementation for such approach from my point of view would be something like:
Code:
for each loop function do
write high to XCLK
if VSYNCH is HIGH
return;
if HREF is LOW
return;
if lastPCLOCK was HIGH and currentPCLOCK is LOW
readPixelFromDataPins();
end for
My readPixelFromDataPins() basically read just the first byte (as I'm just testing if I can even read something from the camera), and it is written as follows:
Code:
byte readPixelFromDataPins() {
byte result = 0;
for (int i = 0; i < 8; i++) {
result = result << 1 | digitalRead(data_p[i]);
}
return result;
}
In order to check if something is being read from the camera I just print it to the Serial 9600, the byte read from data pins as a number. But currently I'm receiving only zero values. The code I'm using to retrieve an image is stored here: https://gist.github.com/franciscospaeth/8503747.
Did somebody that makes OV7670 work with Arduino already figure out what am I doing wrong? I suppose I'm using the XCLOCK wrongly right? What shall I do to get it working?
I searched a lot and I didn't found any SSCCE (http://sscce.org/) for this camera using arduino, if somebody have it please let me know.
This question is present on arduino forum (http://forum.arduino.cc/index.php?topic=211741.0) too.
your idea is not bad but ...
the xclock need to be a clock (in your program is just a transition from 0 to 1 and is freezing there)
you need also to use I2C with SIOC and SIOD for configuring the camera (or you can use the default settings, but I am not sure if is the correct output format for you, 30F/s,VGA, YUV format ....)
your code execution is slower using the serial output in the same loop with reading data
I will recommend you to toggle the xclock pin and to move the pixel print in a if(). Also you will be able to read Data only in a very precise time, if you want to read only one byte, than after a transition from 0 to 1 of HREF you need to wait for a new transition from 0 to 1 of PCLK (you will be able to see only one 0-1 transition of HREF after 784x2 transitions of PCLK, (640 active pixels + 144 dead time for each line) x 2 (for YUV or RGB are 2 bytes received for each pixel) )
Hello I am Mr_Arduino from the arduino forums. Your issue is that you are reading pixels too slow please do not use digital read to do such a thing. Also if you insist on using a separate function just to read a byte make sure the function is being inlined. You can do this by declaring your function as static inline. Also as mentioned above how are you generating the clock. You can generate the XCLK using PWM on the arduino.
I have created a working example here:
https://github.com/ComputerNerd/arduino-camera-tft/blob/master/captureimage.c
Edit: a 3rd party has copied part but not all of the code from the above link into the answer here. However, the link must remain as the code posted below requires additional files from that source to actually work.
Edit 2: Removed irrelevant code. You will need to modify what you do with the data.
void capImg(void){
cli();
uint8_t w,ww;
uint8_t h;
w=160;
h=240;
tft_setXY(0,0);
CS_LOW;
RS_HIGH;
RD_HIGH;
DDRA=0xFF;
//DDRC=0;
#ifdef MT9D111
while (PINE&32){}//wait for low
while (!(PINE&32)){}//wait for high
#else
while (!(PINE&32)){}//wait for high
while (PINE&32){}//wait for low
#endif
while (h--){
ww=w;
while (ww--){
WR_LOW;
while (PINE&16){}//wait for low
PORTA=PINC;
WR_HIGH;
while (!(PINE&16)){}//wait for high
WR_LOW;
while (PINE&16){}//wait for low
PORTA=PINC;
WR_HIGH;
while (!(PINE&16)){}//wait for high
WR_LOW;
while (PINE&16){}//wait for low
PORTA=PINC;
WR_HIGH;
while (!(PINE&16)){}//wait for high
WR_LOW;
while (PINE&16){}//wait for low
PORTA=PINC;
WR_HIGH;
while (!(PINE&16)){}//wait for high
}
}
CS_HIGH;
sei();
}
You can also find it on github.
You can use my instruction: how to retrieve image from ov7670 It contains all the steps you need. There is also instuction to setup FrameGrabber: how to run framegrabber

Autohotkey: Send mouse-click (or key-press) without triggering handler

I have an AutoHotkey script in which the left-mouse-button is mapped to a function. Part of the function includes simulating a left-button click offset from the actual cursor position. Not surprisingly, this ends up becoming a bit of an infinite loop.
Likewise, there is a handler that traps a key-press and performs some math before passing the key-press on through.
Is there a way perform a click without triggering the click-handler? Similarly, is there a way to send a key-press without triggering the key-press-handler?
Trap() {
MouseGetPos, x,y
;Perform some math with x and y
Click %x% %y% left ;oops, this causes Trap to get called again
}
LButton:: Trap
From the AutoHotkey manual:
$ - This is usually only necessary if the script uses the Send command to send the keys that comprise the hotkey itself, which might otherwise cause it to trigger itself.
That does the trick:
$LButton:: Trap
I actually do not see the looping behaviour you describe, so I wonder if there is some other factor at play.
If that really is the problem, then you can use a boolean flag to prevent recursive execution:
isTrapping := false
Trap() {
global isTrapping
if isTrapping = true
return
isTrapping := true
MouseGetPos x, y
; do some maths with x & y
Click %x%, %y%
isTrapping := false
}
LButton::Trap()