2010-03-22 1 views
1

Я пытаюсь использовать функцию выбора и копирования IKImageView. Если все, что вы хотите сделать, это приложение с изображением, выберите часть и скопируйте ее в буфер обмена, это легко. Вы устанавливаете выбор меню копирования для копирования первого экземпляра ответа: (id), и магически все работает.Другой вопрос IKImageView: копирование области

Однако, если вам нужно что-то более сложное, например, вы хотите скопировать как часть какой-либо другой операции, я не могу найти способ сделать это.

У IKImageView, похоже, нет метода копирования, он, похоже, не имеет метода, который даже скажет вам выбранный прямоугольник!

Я прошел через книгу Hillegass', так что я понимаю, как работает с буфером обмена, но только не как получить часть изображения, вне поля зрения ...

Теперь, я начинаю думать, что Я ошибся в том, чтобы основывать свой проект на IKImageView, но это то, на чем был построен «Превью» (или так я читал), поэтому я решил, что он должен быть стабильным ... и так или иначе, теперь уже слишком поздно, я тоже глубоко в этом, чтобы начать заново ...

Так, кроме использования IKImageView каких-либо предложений о том, как скопировать область выбора в буфер обмена вручную?

EDIT на самом деле, я нашел способ копирования (ИН), но когда я называю его, я получаю

<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 16 bits/pixel; 1-component color space; kCGImageAlphaPremultipliedLast; 2624 bytes/row. 

который, очевидно, не происходит, когда я делаю обычную копию через первый Ответчик ... Я понимаю сообщение об ошибке, но я не уверен, где он получает эти параметры от ...

Есть ли способ проследить это и посмотреть, как это происходит? Отладчик не поможет по очевидным причинам, а также тот факт, что я делаю это в Mozilla, поэтому отладчик не является вариантом в любом случае ...

EDIT 2 Мне кажется, что copy: (id) метод, который я нашел, может копировать VIEW, а не копировать кусок изображения в буфер обмена, и это то, что мне нужно.

Причина, по которой я думал, что это копия буфера обмена, заключается в том, что в другом проекте, где я копирую из IKImageView в буфер обмена прямо из меню редактирования, он просто отправляет копию: (id) первому ответу, но Я на самом деле не уверен, что firstresponder делает с ним ...

EDIT 3 оказывается, что ошибка CGBitmapContextCreate исходит от [imageView image] который, как ни странно, IS документированный способ.

Возможно, это происходит потому, что я помещаю изображение там с помощью метода setImage: (id), передавая ему NSImage * ... Есть ли какой-нибудь другой, более умный способ получить NSImage в IKImageView?

+0

Вы можете определенно отладки плагинов во внешнем приложении, например, Mozilla/Firefox. Просто создайте пользовательский исполняемый файл в своем проекте Xcode и укажите его на приложение, которое вы хотите отлаживать. Я сделал это очень успешно с Safari, Dreamweaver, Adobe GoLive и другими. –

+0

«Мне кажется, что метод« copy: (id) », который я нашел, может копировать VIEW, а не копировать кусок изображения в буфер обмена ...» Нет. Вы думаете о 'copy' (обратите внимание на аргументы), который возвращает копию объекта и не работает с представлениями. 'copy:' (один аргумент) '- это действие, которое сообщает приемнику (представлению) скопировать его выбор в буфер обмена. –

ответ

0

Метод -copy: в IKImageView делает то, что каждый другой -copy: способ: он копирует текущий выбор в буфер обмена. Однако по какой-то причине он реализован как частный метод в IKImageView.

Вы можете просто позвонить непосредственно:

[imageView copy:nil]; 

Это будет копировать все, что в данный момент выбран в буфер обмена.

Я не думаю, что есть способ прямого доступа к содержимому изображения текущего выбора в IKImageView с использованием общедоступных методов, это хороший кандидат на отчет об ошибке/запрос функции.

Вы можете, однако, использовать частный метод -selectionRect получить CGRect текущего выбора и использовать, чтобы извлечь выделенную часть изображения:

//stop the compiler from complaining when we call a private method 
@interface IKImageView (CompilerSTFU) 
- (CGRect)selectionRect 
@end 

@implementation YourController 
//imageView is an IBOutlet connected to your IKImageView 
- (NSImage*)selectedImage 
{ 
    //get the current selection 
    CGRect selection = [imageView selectionRect]; 

    //get the portion of the image that the selection defines 
    CGImageRef selectedImage = CGImageCreateWithImageInRect([imageView image],(CGRect)selection); 

    //convert it to an NSBitmapImageRep 
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease]; 
    CGImageRelease(selectedImage); 

    //create an image from the bitmap data 
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease]; 

    //in 10.6 you can skip converting to an NSBitmapImageRep by doing this: 
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];  
    return image; 
} 
@end 
+0

Не забудьте проверить, реагирует ли 'imageView' на' selectionRect'. Поскольку это частный метод, Apple может в любое время переименовать, изменить или удалить этот метод, нарушив ваш код, если он отправит это сообщение безоговорочно. –

+0

Когда я попробую [imageView copy: nil], я получаю : CGBitmapContextCreate: неподдерживаемая комбинация параметров: 8 целых бит/компонент; 16 бит/пиксель; 1-компонентное цветовое пространство; kCGImageAlphaPremultipliedLast; 2624 байта/строка. –

+0

И я получаю ту же ошибку, когда я пробую ваш метод ... –

0

Ok, так что копия: ноль не удается, и изображение [imageView] выходит из строя, но оказывается, что у меня есть еще одна копия NSImage с того момента, когда я добавила его в представление, в первую очередь, поэтому я мог это сделать. Кроме того, CGImageCreateWithImageInRect ожидает, что CGImageRef не является NSImage *, поэтому мне пришлось сделать некоторые преобразования.

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

И по какой-то причине, компилятор вдруг начал жаловаться, что NSRect не тот же тип CGRect (что означает, что он вдруг пошел от 32 до 64 бит или что-то ... не знаю, почему ...)

Во всяком случае, вот моя копия selectedImage:

- (NSImage*)selectedImage 
{ 
    //get the current selection 
    CGRect selection = flipCGRect(imageView, [imageView selectionRect]); 

    //get the portion of the image that the selection defines 
    struct CGImage * full = [[doc currentImage] CGImageForProposedRect: NULL context: NULL hints: NULL]; 

    CGImageRef selectedImage = CGImageCreateWithImageInRect(full, selection); 


    //convert it to an NSBitmapImageRep 
    NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:selectedImage] autorelease]; 
    CGImageRelease(selectedImage); 

//  //create an image from the bitmap data 
    NSImage* image = [[[NSImage alloc] initWithData:[bitmap TIFFRepresentation]] autorelease]; 

//  //in 10.6 you can skip converting to an NSBitmapImageRep by doing this: 
    //NSImage* image = [[NSImage alloc] initWithCGImage:selectedImage size:NSZeroSize];  
    return image; 

} 

Я написал flipCGRect и [DOC] currentImage возвращает NSImage * ...