Rust screenshot via windows, keep getting old data - windows

Sorry if this has been answered somewhere but i've been trying to look for similar questions but have yet to find something that works for me.
Im trying to get pixel data from a specific window using the windows crate. My code looks like this:
let handle = FindWindowA(None, "Some Title");
let screen = GetDC(handle);
let dst_screen = CreateCompatibleDC(screen);
let captured_hbmp = CreateCompatibleBitmap(screen, 100, 100);
let hbmp_replace = SelectObject(dst_screen, captured_hbmp);
BitBlt(
dst_screen,
0,
0,
100,
100,
screen,
0,
0,
SRCCOPY,
);
let mut vec :Vec<u8> = vec![0; 100 * 100 * 4];
GetBitmapBits(
captured_hbmp,
100 * 100 * 4,
vec.as_mut_ptr() as *mut c_void
);
ReleaseDC(handle, screen);
SelectObject(dst_screen, hbmp_replace);
DeleteDC(dst_screen);
DeleteObject(captured_hbmp);
return vec;
Whenever i read the values in vec, it contains old data (seconds, minutes and even hours old data). Im guessing this is due to me not cleaning up correctly but i cant for the life of me understand where.
Any ideas?

Related

How do I get this XWindows.XGetImage call right?

(update: the XGetPixel problem has been solved thanks to David)
I am practicing some tasks from rosettacode.org for Standard ML, and I am stuck with the XGetImage call from XWindows (PolyML) . I get a badValue error for every attempt in XYPixmap format.
What I did, was
open XWindows ;
val disp = XOpenDisplay "" ;
val win = XCreateSimpleWindow (RootWindow disp) origin (Area {x=0,y=0,w=300,h=100}) 2 0 0xffffff ;
XMapWindow win;
XFlush disp ;
XGetImage win (Area {x=0,y=0,w=100,h=100}) AllPlanes XYPixmap ;
The XGetImage call returns
X Error BadValue in XGetImage
Exception- XWindows "XGetImage failed" raised
The xwindows.cpp source does not make me much wiser:
XImage *image = XGetImage(d,drawable,x,y,w,h,mask,CImageFormat(format));
if (image == 0) RaiseXWindows(taskData, "XGetImage failed");
ZPixmap + XGetPixel work fine in the most recent polyversion, the rest of this post has been solved:
When I try ZPixmap, i get
val im = XGetImage win (Area {x=0,y=0,w=1,h=1}) AllPlanes ZPixmap ;
val im =
XImage
{bitmapBitOrder = MSBFirst, bitmapPad = 32, bitmapUnit = 32,
bitsPerPixel = 1, byteOrder = MSBFirst, bytesPerLine = 4, data =
ImageData
"\^A\^#\^#\^# ... repeat 22 x .... \^A\^#\^#\^#",
depth = 24, format = ZPixmap, size =
Rect {bottom = 1, left = 0, right = 1, top = 0}, ...}
but
XGetPixel disp im (XPoint {x=0,y=0}) ;
crashes PolyML
The XGetImage example (in C) in the Xlib Programming Manual chapter 6.4.2 does not seem to do anything special, just use the display and a visible window. My window win is visible. I also tried the root window, and that does not work either. I think I have followed the PolyML for X manual correctly.
What is missing here ?
It seems there was a bug in the code that implemented XGetPixel in Poly/ML. There is a fix for that now in the github repository. I'm not familiar enough with X-windows to be able to say whether it should work with XYPixmap.

Error: Use of unresolved identifier 'kCGBlendModeMultiply'

I recently updated to Xcode 7, beta 3.
And I've run into some issues, I can't seem to find any questions for on SO.
When I run my application, i get 3 errors:
Use of unresolved identifier 'kCGBlendModeMultiply'
Use of unresolved identifier 'kCGLineCapRound'
Use of unresolved identifier 'kCGLineJoinMiter'
However the 2 latter ones, disappear, although I assume they will show up after the first one is fixed (hence why I included it in this question).
I didn't see anything in the release notes about these being removed? So I'm a bit stuck at what to do. I tried rewriting the lines of course, but the 3 things I used don't show up as options anymore. In case that they are just gone in the latest Swift 2.0, what can I use instead?
Here's the code for the first error.
func alpha(value:CGFloat)->UIImage
{
UIGraphicsBeginImageContextWithOptions(self.size, false, 0.0)
let ctx = UIGraphicsGetCurrentContext()
let area = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height)
CGContextSetBlendMode(ctx, kCGBlendModeMultiply)
CGContextSetAlpha(ctx, value)
CGContextDrawImage(ctx, area, self.CGImage)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage;
}
Here's the code for the 2 latter errors:
for layer in [ self.top, self.middle, self.bottom ] {
layer.fillColor = nil
layer.strokeColor = UIColor.whiteColor().CGColor
layer.lineWidth = 4
layer.miterLimit = 4
layer.lineCap = kCALineCapRound
layer.masksToBounds = true
let strokingPath = CGPathCreateCopyByStrokingPath(layer.path, nil, 4, kCGLineCapRound, kCGLineJoinMiter, 4)
layer.bounds = CGPathGetPathBoundingBox(strokingPath)
layer.actions = [
"strokeStart": NSNull(),
"strokeEnd": NSNull(),
"transform": NSNull()
]
self.layer.addSublayer(layer)
}
Any help would be greatly appreciated! :)
This should work:
CGContextSetBlendMode(ctx, CGBlendMode.Multiply)
... or even just this:
CGContextSetBlendMode(ctx, .Multiply)
If you Ctrl-click on CGContextSetBlendMode and then from its declaration jump (in the same way) to declaration of CGBlendMode then you will see:
enum CGBlendMode : Int32 {
/* Available in Mac OS X 10.4 & later. */
case Normal
case Multiply
case Screen
case Overlay
// ...
}
Similarly, the other line that produces the error should be changed to:
let strokingPath = CGPathCreateCopyByStrokingPath(layer.path, nil, 4, .Round, .Miter, 4)

Swift: get more detailed info on function parameter type error

I'm using Xcode 6.3.1 and Swift.
When a function with multiple parameter get some error on parameter type, it's hard to know which argument is wrong.
For example, CGBitmapContextCreate(), this code:
let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGBitmapInfo(CGImageAlphaInfo.PremultipliedLast.rawValue)
let context = CGBitmapContextCreate(nil, UInt(size.width), UInt(size.height), 8, 0, colorSpace, bitmapInfo)
will produce an error like this:
MyFile.swift:23:19: Cannot invoke 'CGBitmapContextCreate' with an argument list of type '(nil, UInt, UInt, Int, Int, CGColorSpace, CGBitmapInfo)'
By comparing the document and my argument list carefully, I can find that it is the 2nd and 3rd arguments, which should be Int.
Is there any way to make the compiler more smarter on this?
The problem is probably that the online documentation you are looking at for CGBitmapContextCreate is wrong based on the definition you are actually accessing when you are compiling.
The last parameter needs to be of type UInt32 , and CGBitmapInfo is returning a CGBitmapInfo object. That is why the compiler is erring. You are passing in the wrong type of parameters. You can even right click the function and click "see definition", this will verify what I am saying.
Try instead, passing in CGImageAlphaInfo.PremultipliedLast.rawValue directly, as it is the UInt32 that is being looked for.
Example Solution:
let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo = CGImageAlphaInfo.PremultipliedLast.rawValue
let context = CGBitmapContextCreate(nil, UInt(size.width), UInt(size.height), 8, 0, colorSpace, bitmapInfo)
You'll find that you will be able to compile the source, and get the expected result. Note that you can still apply any bitwise operations you want to on this value.
PS: I had the same issue you were having, and was amply frustrated when I couldn't find a solution.
It works!
let width = CGImageGetWidth(image)
let height = CGImageGetHeight(image)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let bytesPerRow = 4 * width;
let bitsPerComponent :Int = 8
let pixels = UnsafeMutablePointer<UInt8>(malloc(width*height*4))
var context = CGBitmapContextCreate(pixels, width, height, bitsPerComponent, bytesPerRow, colorSpace, CGBitmapInfo())

Sprite Kit Swift Jumping Character

Right now, I am trying to use impulses/forces to make my character jump. I was using gravity so it looks like they are jumping, but the sizes of the jumps were different overtime. Here is my code for attempting to make the character jump, but when I do it, it does not work.
Here is the jumping code I have right now:
func Bigpersonjump () {
BigPerson.physicsBody?.velocity = CGVectorMake(0.0, 0.0)
BigPerson.physicsBody?.applyImpulse(CGVectorMake(0.0, 10.0))
println("Detected")
}
Here is the code for spawning the character:
self.BigPerson = SKSpriteNode(imageNamed: "1")
//self.BigPerson = SKSpriteNode(texture: BigPersonTexture)
self.BigPerson.size.height = self.size.height / 8
self.BigPerson.size.width = self.size.width / 13
self.BigPerson.position = CGPointMake(CGRectGetMidX(self.frame) / 2 , self.frame.size.height / 2.2)
self.BigPerson.zPosition = 9
BigPerson.physicsBody = SKPhysicsBody(rectangleOfSize: BigPerson.size)
BigPerson.physicsBody?.usesPreciseCollisionDetection = true
BigPerson.physicsBody?.dynamic = false
BigPerson.physicsBody?.categoryBitMask = BodyType.BigPersonCategory.rawValue
BigPerson.physicsBody?.allowsRotation = false
BigPerson.physicsBody?.collisionBitMask = BodyType.ScoreCategory.rawValue
BigPerson.physicsBody?.contactTestBitMask = BodyType.ScoreCategory.rawValue
var distanceToMove = CGFloat(self.frame.size.width + 2.0 * BigPerson.size.width)
var moveBigPerson = SKAction.moveByX(distanceToMove * 5.3, y: 0.0, duration: NSTimeInterval (0.02 * distanceToMove))
BigPerson.runAction(moveBigPerson)
BigPerson.runAction(LeftSideRunning)
self.addChild(self.BigPerson)
For realistic jump you need to use only applyImpulse, not SKActions (e.g. on user's tap).
Physics body should be dynamic (in your code it is false).
Check different values for impulse value, because you body may be too heavy.
Also please check friction value for both body and surface (as I see in your code you are trying to move it horizontally).
Also try different directions, may be you are trying to jump in the wrong direction.

OutOfMemoryException in Image Resizing

We are using a .net dll (http://imageresizing.net/download) for imageresizing on runtime. It works perfectly. However, it happen after some time (between 1-7 days) that system started to raise exception in the even viewer:
Exception information:
Exception type: OutOfMemoryException
Exception message: Insufficient memory to continue the execution of the program.
And after that exception the website usually stop working with the error throwing "System.OutOfMemoryException".
And if we "recycle" the application pool in which the website is running, it clears the problem and website get back to normal immediately without any code change.
Before imagereiszing dll, we were using our custom code and same problem happen with that too. Following is the code.
private Bitmap ConvertImage(Bitmap input, int width, int height, bool arc)
{
if (input.PixelFormat == PixelFormat.Format1bppIndexed ||
input.PixelFormat == PixelFormat.Format4bppIndexed ||
input.PixelFormat == PixelFormat.Format8bppIndexed)
{
Bitmap unpackedBitmap = new Bitmap(input.Width, input.Height);
Graphics g = Graphics.FromImage(unpackedBitmap);
g.Clear(Color.White);
g.DrawImage(input, new Rectangle(0,0,input.Width, input.Height));
g.Dispose();
input = unpackedBitmap;
}
double aspectRatio = (double)input.Height / (double)input.Width;
int actualHeight = CommonMethods.GetIntValue(Math.Round(aspectRatio * width, 0));
Bitmap _imgOut;
if (actualHeight > height)
{
ResizeImage resizeImage = new ResizeImage(width, actualHeight, InterpolationMethod.Bicubic);
Bitmap _tempBitmap = resizeImage.Apply(input);
Bitmap _croppedBitmap = new Bitmap(width, height);
Graphics _crop = Graphics.FromImage(_croppedBitmap);
_crop.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
_crop.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_crop.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
_crop.DrawImageUnscaledAndClipped(_tempBitmap, new Rectangle(0, 0, width, height));
_crop.Dispose();
_imgOut = _croppedBitmap;
}
else
{
ResizeImage resizeImage = new ResizeImage(width, height, InterpolationMethod.Bicubic);
_imgOut = resizeImage.Apply(input);
}
// Draw the arc if it has been requested
if (arc)
{
Graphics _arc = Graphics.FromImage(_imgOut);
_arc.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
_arc.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_arc.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
_arc.DrawArc(new Pen(Color.White, 24), new Rectangle(-13, -13, 50, 50), 180, 90);
_arc.Dispose();
}
// job done
return _imgOut;
}
We are resizing image like: www.mysite.com/images/myimage.jpg?width=196&height=131
Looking forward.
Farrukh
When you encounter an OutOfMemoryException (regardless of where it occurs), it can be caused by a memory leak anywhere in the application. Having debugged dozens of these instances with WinDbg, I've never found any that ended up being due to a bug in http://imageresizing.net.
That said, there's an easy way to determine whether it is a problem with http://imageresizing.net or not; create a separate application pool and subfolder application in IIS for your images and image resizing. Install nothing there except the image resizer. Next time you encounter the error, log on to the server and find out which w3wp.exe instance is responsible for the massive memory usage.
If it's in the ImageResizer app pool, go collect your $20-$50 bug bounty from http://imageresizing.net/support. If not, you need to figure out where you're leaking stuff in your main application.
If you're working with System.Drawing anywhere else in the app, that's the first place to look. Check your code against this list of pitfalls.
If you're positive you're disposing of every System.Drawing.* instance in a using or finally clause, then read this excellent article a few times to make sure you're not failing on any of the basics, then dig in with DebugDiag and/or WinDBG (see bottom of article).

Resources