[OSX] Screenshot
Übersicht

MacintoshBetreff: [OSX] Screenshot |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hey.
Ich habe gestern aus langer weile bissle an ner funktin rumgefummelt, das man screenshots machen kann, und diese dann als pixmap hat. Die funktion hat allerdings noch Fehler, und ist nicht grade "sauber gecodet", so lässt sich mit dem Pixmap auser es zu zeichnen fast nichts machen. screenshot.m Code: [AUSKLAPPEN] #import <AppKit/AppKit.h> typedef struct bbpixmap bbpixmap; struct bbpixmap{ void *class; int refs; unsigned char *pixels; int width,height,pitch,format,capacity; }; const static char BytesPerPixel[]={0,1,1,3,3,4,4}; bbpixmap * BBPixmapWithCGImage(CGImageRef image, int format, int align) { NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; struct bbpixmap * pixmap; int bytesPerPixel, bitsPerPixel, bytesPerRow; int height, width; unsigned char * data; BOOL alpha = NO; bytesPerPixel = [bitmap samplesPerPixel]; bitsPerPixel = [bitmap bitsPerPixel]; bytesPerRow = [bitmap bytesPerRow]; height = CGImageGetHeight(image); width = CGImageGetWidth(image); data = [bitmap bitmapData]; pixmap->width = width; pixmap->height = height; pixmap->format = format; pixmap->pitch = (width*BytesPerPixel[format]+(align-1))/align*align; pixmap->capacity = pixmap->pitch*height; pixmap->pixels = malloc(pixmap->capacity); int i; for (i = 0; i < height; i++) { memcpy(pixmap->pixels + (i*pixmap->pitch), data + (i*bytesPerRow+1), bytesPerRow); } [bitmap release]; CGImageRelease(image); return pixmap; } bbpixmap * captureScreen( int a ) { CGImageRef image = CGDisplayCreateImage(CGMainDisplayID()); return BBPixmapWithCGImage(image, 6, a); } bbpixmap * captureScreenRect( float x, float y, float w, float h ) { CGRect rect; rect.origin.x = x; rect.origin.y = y; rect.size.width = w; rect.size.height = h; CGImageRef image = CGDisplayCreateImageForRect(CGMainDisplayID(), rect); return BBPixmapWithCGImage(image, 6, 4); } void freePixmap(bbpixmap * pixmap) { pixmap->refs = 0; free(pixmap->pixels); pixmap->width = 0; pixmap->height = 0; pixmap->pitch = 0; pixmap->format = 0; pixmap->capacity = 0; } screenshot.bmx BlitzMax: [AUSKLAPPEN]
viel spaß. Vieleicht hat ja jemand lust das zu verbessern, sodas es ordentlich funktioniert :) |
||
joasia36 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
ich versteh zwar nicht warum, aber bei mir crashed der c-code beim ersten zugriff auf die bbpixmap:
pixmap->width = width; hat irgendjemand eine Idee? |
||
![]() |
d-bug |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo joasia36,
ich nehme mal an du hast bereits Lion, oder? Während unter Snow-Leopard Macintoshs Code noch ohne Probleme lief, wird unter Lion einfach keine Instanz des structs bbpixmap erstellt. Weil es diese nicht gibt, stürzt die Applikation eben kommentarlos ab, wenn das erste mal darauf zugegriffen werden soll. Folgende kleine Änderung sollte dir weiter helfen: Code: [AUSKLAPPEN] #import <AppKit/AppKit.h> typedef struct bbpixmap bbpixmap; struct bbpixmap{ void *class; int refs; unsigned char *pixels; int width,height,pitch,format,capacity; }; const static char BytesPerPixel[]={0,1,1,3,3,4,4}; bbpixmap * BBPixmapWithCGImage(bbpixmap *pixmap, CGImageRef image, int format, int align) { NSBitmapImageRep * bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; int bytesPerPixel, bitsPerPixel, bytesPerRow; int height, width; unsigned char * data; BOOL alpha = NO; bytesPerPixel = [bitmap samplesPerPixel]; bitsPerPixel = [bitmap bitsPerPixel]; bytesPerRow = [bitmap bytesPerRow]; height = CGImageGetHeight(image); width = CGImageGetWidth(image); data = [bitmap bitmapData]; pixmap->width = width; pixmap->height = height; pixmap->format = format; pixmap->pitch = (width*BytesPerPixel[format]+(align-1))/align*align; pixmap->capacity = pixmap->pitch*height; pixmap->pixels = malloc(pixmap->capacity); int i; for (i = 0; i < height; i++) { memcpy(pixmap->pixels + (i*pixmap->pitch), data + (i*bytesPerRow+1), bytesPerRow); } [bitmap release]; CGImageRelease(image); return pixmap; } bbpixmap * captureScreen(bbpixmap *pixmap, int a ) { CGImageRef image = CGDisplayCreateImage(CGMainDisplayID()); return BBPixmapWithCGImage(pixmap, image, 6, a); } bbpixmap * captureScreenRect(bbpixmap *pixmap, float x, float y, float w, float h ) { CGRect rect; rect.origin.x = x; rect.origin.y = y; rect.size.width = w; rect.size.height = h; CGImageRef image = CGDisplayCreateImageForRect(CGMainDisplayID(), rect); return BBPixmapWithCGImage(pixmap, image, 6, 4); } void freePixmap(bbpixmap * pixmap) { pixmap->refs = 0; free(pixmap->pixels); pixmap->width = 0; pixmap->height = 0; pixmap->pitch = 0; pixmap->format = 0; pixmap->capacity = 0; } ...und damit man auch was sehen kann: BlitzMax: [AUSKLAPPEN] Import "screenshot.m" Ich habe in dieser kleinen Änderung lediglich dafür gesorgt, dass BlitzMax eine fertige Instanz von TPixmap an Objektive-C übergibt, die Objektive-C nur noch ausfüllen braucht. So funktionierst dann auch unter Lion wieder. Es gibt bestimmt auch einen eleganteren Fix dafür, allerdings hab ich zu wenig Ahnung von structs um das geschmeidiger zu lösen. @Macintosh: Verzeih meine Einmischung. ![]() |
||
joasia36 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
ja, danke, hatte den Fehler auch inzwischen gefunden.
Habe das Problem allerdings über einen malloc gelöst. Sind noch zwei ganz nette Funktionen hinzugekommen; falls Interesse besteht: Code: [AUSKLAPPEN] #import <AppKit/AppKit.h>
typedef struct bbpixmap{ void *class; int refs; unsigned char *pixels; int width, height, pitch, format, capacity; } bbpixmap; const static char BytesPerPixel[]={0,1,1,3,3,4,4}; bbpixmap *BBPixmapWithCGImage(CGImageRef image, int format, int align) { NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:image]; bbpixmap *pixmap; pixmap = malloc(sizeof(bbpixmap)); int bytesPerPixel, bitsPerPixel, bytesPerRow; int height, width; unsigned char *data; BOOL alpha = NO; bytesPerPixel = [bitmap samplesPerPixel]; bitsPerPixel = [bitmap bitsPerPixel]; bytesPerRow = [bitmap bytesPerRow]; height = CGImageGetHeight(image); width = CGImageGetWidth(image); data = [bitmap bitmapData]; pixmap->width = width; pixmap->height = height; pixmap->format = format; pixmap->pitch = (width*BytesPerPixel[format]+(align-1))/align*align; pixmap->capacity = pixmap->pitch*height; pixmap->pixels = malloc(pixmap->capacity); int i; for (i = 0; i < height; i++) { memcpy(pixmap->pixels + (i*pixmap->pitch), data + (i*bytesPerRow+1), bytesPerRow); } [bitmap release]; CGImageRelease(image); return pixmap; } void freePixmap(bbpixmap *pixmap) { free(pixmap->pixels); free(pixmap); } bbpixmap *pixmapWithScreen(int a) { CGImageRef image = CGDisplayCreateImage(CGMainDisplayID()); return BBPixmapWithCGImage(image, 6, a); } bbpixmap *pixmapWithScreenRect(float x, float y, float w, float h) { CGRect rect = CGRectMake(x, y, w, h); CGImageRef image = CGDisplayCreateImageForRect(CGMainDisplayID(), rect); return BBPixmapWithCGImage(image, 6, 4); } bbpixmap *NSPixmapWithWindow(NSWindow *window) { CGWindowID windowID = [window windowNumber]; CGImageRef windowImage = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageBoundsIgnoreFraming); if(CGImageGetWidth(windowImage) <= 1) { CGImageRelease(windowImage); return nil; } return BBPixmapWithCGImage(windowImage, 6, 4); } bbpixmap *NSPixmapBelowWindow(NSWindow *window) { CGWindowID windowID = [window windowNumber]; CGRect windowRect = NSRectToCGRect( [window frame] ); windowRect.origin.y = NSMaxY([[window screen] frame]) - NSMaxY([window frame]); CGImageRef capturedImage = CGWindowListCreateImage( windowRect, kCGWindowListOptionOnScreenBelowWindow, windowID, kCGWindowImageDefault ); if(CGImageGetWidth(capturedImage) <= 1) { CGImageRelease(capturedImage); return nil; } return BBPixmapWithCGImage(capturedImage, 6, 4); } und dann noch: Code: [AUSKLAPPEN] Import "screenshot.m"
Import MaxGui.Drivers Extern Function pixmapWithScreen:TPixmap(align_bytes:Int=4) Function pixmapWithScreenRect:TPixmap(x:Float, y:Float, w:Float, h:Float) 'geht! Function NSPixmapWithWindow:TPixmap(NSWindow) Function NSPixmapBelowWindow:TPixmap(NSWindow) Function freePixmap(p:TPixmap) End Extern Function pixmapWithWindow:TPixmap(window:TGadget) Local NSWindow = QueryGadget(window, QUERY_NSVIEW) If GadgetClass(window) = GADGET_WINDOW And NSWindow Return NSPixmapWithWindow(NSWindow) End Function Function pixmapBelowWindow:TPixmap(window:TGadget) Local NSWindow = QueryGadget(window, QUERY_NSVIEW) If GadgetClass(window) = GADGET_WINDOW And NSWindow Return NSPixmapBelowWindow(NSWindow) End Function Local window:TGadget = CreateWindow( AppTitle, 100, 100, 320, 240, Null, WINDOW_TITLEBAR|WINDOW_RESIZABLE|WINDOW_STATUS) SetStatusText( window, "hello world! - press any key to continue..." ) While Not ActiveGadget(); Wend ' wait for the window to appear Local a:TPixmap = pixmapWithScreen() Local b:TPixmap = pixmapWithScreenRect(1000,0,440,250) Local c:TPixmap = pixmapWithWindow(window) Local d:TPixmap = pixmapBelowWindow(window) Graphics 1440, 900,32 SetBlend ALPHABLEND SetAlpha 0.2 SetColor 0,0,0 DrawPixmap(a,0,0); freepixmap(a) DrawRect 40,250,300,30 DrawRect 590,120,PixmapWidth(b)+20,PixmapHeight(b)+40 DrawRect 40,440,PixmapWidth(c )+20,PixmapHeight(c )+40 DrawRect 590,440,PixmapWidth(d)+20,PixmapHeight(d)+40 SetAlpha 1 DrawText "captureScreen()",50,255 DrawText "captureScreenRect()",600,125 DrawText "imageWithWindow()",50,445 DrawText "imageBelowWindow()",600,445 DrawPixmap(b,600,150); freepixmap(b) DrawPixmap(c,50,470); freepixmap(c ) DrawPixmap(d,600,470); freepixmap(d) Flip WaitKey Sorry wegen der Änderung der Funktionsnamen, erschien mir so allerdings stimmiger. Könnte man schon fast ein Modul raus machen. BTW: in welchem Header sind eigentlich bbpixmap und BytesPerPixel deklariert (include/import scheint mir hier sinnvoll?). Die beiden zusätzlichen Funktionen habe ich mir übrigens hier abgeschaut: http://www.cocoadev.com/index.pl?ScreenShotCode |
||
Macintosh |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Höhö das ja schon ein weilchen her..
da konnte ich noch garkein C, also nicht so richtig ^^ Aber freut mich das der code interessiert :) |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group