Сделать снимок экрана NSView или NSWindow программно? - PullRequest
1 голос
/ 20 сентября 2019

Мне нужно захватить мой NSView на изображение.Сделать снимок NSWindow также будет хорошо - я могу просто обрезать необходимый вид позже.

У меня есть два требования: (1) у меня есть полупрозрачные кнопки на виде;(2) Мне нужно получить снимок, даже если изображение частично выходит за пределы экрана.

Это изображение, которое я хочу захватить:

enter image description here

Я попробовал эти четыре метода, и ни один из них не может сделать то, что я хочу.

Метод 1.

NSImage *image = [[NSImage alloc] initWithData:[view dataWithPDFInsideRect:viewRect]];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];

Этот метод сохраняет прозрачность кнопки, но игнорирует ее слойдополнения, такие как причудливая рамка:

enter image description here

Метод 2.

Это рекомендуемый метод для захвата содержимого NSView:

NSBitmapImageRep *imageRep = [view bitmapImageRepForCachingDisplayInRect:viewRect];
[view cacheDisplayInRect:viewRect toBitmapImageRep:imageRep];
NSImage *image = [[NSImage alloc] initWithSize:viewRect.size];
[image addRepresentation:imageRep];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];

Этот метод сохраняет элементы слоя, но игнорирует прозрачность кнопки:

enter image description here

Метод 3.

Этот метод просто отображаетпросмотр слоя в изображении:

NSImage *image = [[NSImage alloc] initWithSize:viewRect.size];
[image lockFocus];
CGContextRef ctx = [NSGraphicsContext currentContext].graphicsPort;
[view.layer renderInContext:ctx];
[image unlockFocus];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];

Этот метод также сохраняет элементы слоя, но игнорирует прозрачность кнопки:

enter image description here

Метод 4.

CGImageRef cgimg = CGWindowListCreateImage(CGRectZero, kCGWindowListOptionIncludingWindow, (int)self.window.windowNumber, kCGWindowImageBoundsIgnoreFraming);
NSImage *image = [[NSImage alloc] initWithCGImage:cgimg size:viewRect.size];
NSData *imageData = [image TIFFRepresentation];
[imageData writeToFile:fName atomically:NO];

Этот метод сохраняет как свойства слоя, так и прозрачность кнопок, но если представление частично выходит за пределы экрана, тогдане отображать ту часть, которая находится вне экрана:

enter image description here

Итак, что я делаю не так?Как получить снимок экрана так же, как это делает системная утилита захвата экрана?

...