Как я могу использовать CGContextDrawTiledImage для мозаичного изображения? - PullRequest
8 голосов
/ 25 марта 2009

Я хочу иметь возможность создавать объект пользовательского интерфейса, такой как UIImageView, и размещать изображение внутри него.

Мне удалось использовать CGContextDrawTiledImage для обновления фона в главном окне, но не для просмотра изображений. Я могу сделать это, если я изменю функцию drawRect внутри класса MainView.

Я чувствую, что я близко, но все еще что-то упускаю. Может ли кто-нибудь указать мне правильное направление?

- (void)drawRect:(CGRect)rect {

CGImageRef image = CGImageRetain(currentImage.CGImage);

CGRect imageRect;
imageRect.origin = CGPointMake(160, 240);
imageRect.size = CGSizeMake(320.0, 480.0);

CGContextRef uiContext = UIGraphicsGetCurrentContext();

CGContextClipToRect(uiContext, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height));

CGContextDrawTiledImage(uiContext, imageRect, image);

}

Ответы [ 5 ]

26 голосов
/ 12 июля 2010

Если вы просто хотите расположить изображение на виде, измените его на обычный UIView и добавьте фон UIColor initWithPatternImage:

backgroundView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageWithContentsOfFile:[self bundlePath:@"some_tile_image.png" inDirectory:@"tiles"]]];
17 голосов
/ 02 апреля 2009

Допустим, у вас есть CGImageRef для изображения, которое вы хотите выложить на плитку, под названием tileImage и UIImageView под названием imageView. Вам нужно создать UIImage, чтобы присвоить свойству image значение imageView. Вы можете сделать это так:

CGSize imageViewSize = imageView.bounds.size;
UIGraphicsBeginImageContext(imageViewSize);
CGContextRef imageContext = UIGraphicsGetCurrentContext();
CGContextDrawTiledImage(imageContext, (CGRect){ CGPointZero, imageViewSize }, tileImage);
UIImage *finishedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

imageView.image = finishedImage;

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

2 голосов
/ 29 марта 2009

Вместо того, чтобы пытаться изменить UIImageView, рассмотрите подкласс UIView вместо этого. UIImageView специально разработан для одного не мозаичного изображения, и некоторые из внутренних элементов могут вас испортить. На самом деле он не предназначен для изменения так, как вы описываете.

В подклассе UIView (UITiledImageView?) Вы можете использовать метод drawRect: чтобы делать то, что вы хотите. Вы даже можете создать ivars для изображения, его размера и свойств листов для большей гибкости и расширяемости.

Обновлено с примером проекта: http://github.com/kailoa/6tringle-tiledimageview/tree/master

Соответствующий код чертежа:

- (void)drawRect:(CGRect)rect 
{
    if (TiledImage) {

        //Since we are retaining the image, we append with ret_ref.  this reminds us to release at a later date.
        CGImageRef image_to_tile_ret_ref = CGImageRetain(TiledImage.CGImage); 

        CGRect image_rect;
        image_rect.size = TiledImage.size;  //This sets the tile to the native size of the image.  Change this value to adjust the size of an indivitual "tile."

        CGContextRef context = UIGraphicsGetCurrentContext();

        CGContextDrawTiledImage(context, image_rect, image_to_tile_ret_ref);

        CGImageRelease(image_to_tile_ret_ref);
    }
}
1 голос
/ 31 июля 2011

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

Я просто хочу указать, что ответ от Kailoa Kadano содержит ошибку, image_rect.origin не инициализирован должным образом.

Около 3 недель назад я скопировал его код в свой проект, и он, похоже, работает. Однако вчера я попытался запустить код в симуляторе ios (iphone 4.3), он просто завис в CGContextDrawTiledImage. После добавления следующей строки, как показано в ответе Керемка:

image_rect.origin = CGPointMake(0.0, 0.0);

снова работает!

Это довольно сложно, на самом деле сначала я тестировал на симуляторе iphone 4.3, затем недавно я тестировал на симуляторе iphone 4.0, затем вчера, когда я снова переключился на симулятор 4.3 или симулятор 4.2, возникает проблема. То есть image_rect.origin не определено, иногда это нулевые данные, возможно, иногда оно содержит некоторые случайные данные.

0 голосов
/ 29 марта 2009

Я недавно сделал это, создав пользовательский UIView.

@interface TiledImageView : UIView {
@private
    UIImage *image_;
}

@property (nonatomic, retain) UIImage *image;
@end

и для файла .m:

@implementation TiledImageView
@synthesize image = image_;

- (void)dealloc {
    [image_ release];
    [super dealloc];
}

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // Initialization code
        self.image = [UIImage imageNamed:@"BGTile.png"];

    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    CGImageRef image = CGImageRetain(image_.CGImage);

    CGRect imageRect;
    imageRect.origin = CGPointMake(0.0, 0.0);
    imageRect.size = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));

    CGContextRef context = UIGraphicsGetCurrentContext();   
    CGContextClipToRect(context, CGRectMake(0.0, 0.0, rect.size.width, rect.size.height));  
    CGContextDrawTiledImage(context, imageRect, image);
    CGImageRelease(image);
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...