How can I use CGContextDrawTiledImage to tile an image?

前端 未结 5 1071
死守一世寂寞
死守一世寂寞 2020-12-05 03:36

I want to be able to an UI object like a UIImageView and tile an image inside of it.

I have been able to use CGContextDrawTiledImage to update the background in the

相关标签:
5条回答
  • 2020-12-05 04:01

    Rather than trying to modify a UIImageView, consider subclassing UIView instead. UIImageView is specifically designed for one non-tiled image and some of the internals may be messing you up. It's not really intended to be modified in the way you describe.

    In a subclass of UIView (UITiledImageView?) you can use the drawRect: method to do what you want. You can even create ivars for the image, its size and tiling properties for greater flexibility and extensibility.

    Updated with sample project: http://github.com/kailoa/6tringle-tiledimageview/tree/master

    The relevant drawing code:

    - (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);
        }
    }
    
    0 讨论(0)
  • 2020-12-05 04:08

    If you just want to tile an image in the view, change it to a normal UIView and tile the background with UIColor initWithPatternImage:

    backgroundView.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageWithContentsOfFile:[self bundlePath:@"some_tile_image.png" inDirectory:@"tiles"]]];
    
    0 讨论(0)
  • 2020-12-05 04:15

    Let's say you've got a CGImageRef for the image you want to tile called tileImage and a UIImageView called imageView. What you need to do is create a UIImage to assign to the image property of imageView. You can do that like this:

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

    This will create a bitmap image context of the desired size, tile the image into that context, get a UIImage out of the context, then assign it to the UIImageView. You can really put this code anywhere so long as the image view and tile image are loaded and ready to go.

    0 讨论(0)
  • 2020-12-05 04:24

    Sorry for not knowing how to add comment to other's answers, so I created a new answer here:

    I just want to point out the answer provided by Kailoa Kadano has a bug, the image_rect.origin is not initialized properly.

    About 3 weeks ago, I copied his code in my project, and it seems working. However, yesterday, I tried to run the code in ios simulator(iphone 4.3), it just hang in CGContextDrawTiledImage. After adding the following line as showed in keremk's answer:

    image_rect.origin = CGPointMake(0.0, 0.0);
    

    it works again!

    It's rather tricky, actually at first I tested under iphone 4.3 simulator, then recently I tested under iphone 4.0 simulator, then yesterday when I switched back to 4.3 simulator or 4.2 simulator, the problem occurs. That is the image_rect.origin is undefined, sometimes it's zero data, maybe sometimes it has some random data.

    0 讨论(0)
  • 2020-12-05 04:24

    I recently did this by creating a custom UIView.

    @interface TiledImageView : UIView {
    @private
        UIImage *image_;
    }
    
    @property (nonatomic, retain) UIImage *image;
    @end
    

    and for the .m file:

    @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
    
    0 讨论(0)
提交回复
热议问题