Robię aplikacje która w ciągu sekundy robi parenaście zdjęć pulpitu. Do robienia zrzutów wykorzystuję ten kodL
- (NSImage*) captureScreen
{
int bitsPP, w, h;
int bytesPerRow, bytesPerPixel, numRowBytes;
unsigned char* srcPixels;
unsigned char* dstPixels;
unsigned long index, pRow, srcPix, dstPix, rowLen;
NSImage* resImg;
NSBitmapImageRep* bmapRep;
// screen width & height
w = CGDisplayPixelsWide(kCGDirectMainDisplay );
h = CGDisplayPixelsHigh(kCGDirectMainDisplay );
srcPixels = (unsigned char*) CGDisplayBaseAddress(kCGDirectMainDisplay);
dstPixels = (unsigned char*) malloc( w * h * 4);
bitsPP = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
bytesPerRow = CGDisplayBytesPerRow(kCGDirectMainDisplay);
bytesPerPixel = bitsPP >> 3;
if ( dstPixels != 0 )
{
int y;
numRowBytes = (w * 4);
for (y=0; y < h; y++)
{
rowLen = (unsigned long)(y * bytesPerRow);
for (index=0; index < w; index++)
{
pRow = (index * bytesPerPixel) + rowLen;
srcPix = *((unsigned long*)(srcPixels + pRow));
dstPix = (srcPix >> 24) | ((srcPix & 0x00FFFFFF) << 8);
*((unsigned long*)(dstPixels + pRow)) = dstPix;
}
}
}
bmapRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&dstPixels
pixelsWide:w
pixelsHigh:h bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:numRowBytes
bitsPerPixel:32];
resImg = [[NSImage alloc] initWithSize:[bmapRep size]];
if ( resImg != nil )
{
[resImg addRepresentation:bmapRep];
} else {
NSLog(@"Image is nil");
}
[bmapRep release];
return resImg;
}
Jednak ta metoda daje mi bardzo mały FPS(ledwie klatka na sekunde) więc po chcąc zoptymalizować podzieiłem to na dwie fazy. Podczas startu programu:
@implementation AppController
unsigned char* srcPixels;
unsigned char* dstPixels;
unsigned int indeks, pRow, srcPix, dstPix, rowLen, _u;
int bitsPP, w, h;
int bytesPerRow, bytesPerPixel, numRowBytes;
NSImage* resImg;
NSBitmapImageRep* bmapRep;
- (void) awakeFromNib
{
//Główne informacje zbieranie itp...
w = CGDisplayPixelsWide(kCGDirectMainDisplay );
h = CGDisplayPixelsHigh(kCGDirectMainDisplay );
srcPixels = (unsigned char*) CGDisplayBaseAddress(kCGDirectMainDisplay);
dstPixels = (unsigned char*) malloc( w * h * 4);
bitsPP = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
bytesPerRow = CGDisplayBytesPerRow(kCGDirectMainDisplay);
bytesPerPixel = bitsPP >> 3;
numRowBytes = (w * 4);
}
oraz tą właściwą:
- (NSImage*) captureScreen
{
for (y=0; y < h; y++)
{
rowLen = y * bytesPerRow;
for (indeks=0; indeks < w; indeks++)
{
pRow = (indeks * bytesPerPixel) + rowLen;
srcPix = *((int*)(srcPixels + pRow));
dstPix = (srcPix >> 24) | ((srcPix & 0x00FFFFFF) << 8);
*((int*)(dstPixels + pRow)) = dstPix;
}
}
bmapRep = [[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:&dstPixels
pixelsWide:w
pixelsHigh:h
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:numRowBytes
bitsPerPixel:32];
resImg = [[NSImage alloc] initWithSize:[bmapRep size]];
[resImg addRepresentation:bmapRep];
return resImg;
}
Jednak udało mi się zwiększyć tylko FPS o 3, 4 klatki. Po dokładnej analizie zauważyłem że najwięcej czasu zajmuje przemulenie tych linijek
srcPix = *((int*)(srcPixels + pRow));
*((int*)(dstPixels + pRow)) = dstPix;
Jako że objectiv-C zbyt dobrze do końca nie pojełem to zdaje mi się że jest tu chyba jakieś rzutowanie. Wie może ktoś jak by się dało przyspieszyć ten kod?