2009-06-02 36 views
7

Tôi có tiêu chuẩn UITableViewCell nơi tôi đang sử dụng thuộc tính văn bản và hình ảnh để hiển thị favicon.ico và nhãn. Đối với hầu hết các phần, điều này hoạt động thực sự tốt kể từ khi UIImage hỗ trợ định dạng ICO. Tuy nhiên, một số trang web (như Amazon.com nói) có favicon.ico s sử dụng khả năng lưu trữ nhiều kích thước của tệp ICO trong cùng một tệp. Amazon lưu trữ bốn kích thước khác nhau, tất cả các cách lên đến 48x48.Đặt kích thước UIImage trên hình ảnh UITableViewCell

Kết quả này trong hầu hết các hình ảnh là 16x16 ngoại trừ một số hình ảnh có kích thước 32x32 hoặc 48x48 và khiến mọi thứ trông khủng khiếp. Tôi đã tìm kiếm ở đây, diễn đàn chính thức, tài liệu và những nơi khác mà không thành công. Tôi đã thử tất cả mọi thứ mà tôi có thể nghĩ đến để hạn chế kích thước hình ảnh. Điều duy nhất làm việc là một phương pháp không có giấy tờ, mà tôi không định sử dụng. Đây là ứng dụng đầu tiên của tôi và trải nghiệm đầu tiên của tôi với Cocoa (đến từ C#).

Trong trường hợp tôi không rõ ràng về những gì tôi đang tìm kiếm, lý tưởng là trung tâm xung quanh thiết lập kích thước của UIImage sao cho phiên bản 48x48 sẽ giảm xuống 16x16 hoặc phương pháp để nói UIImage để sử dụng Phiên bản 16x16 có trong tệp ICO. Tôi không nhất thiết cần mã: chỉ là một gợi ý về cách tiếp cận sẽ làm tôi ổn.

Có ai có bất kỳ đề xuất nào không? (Tôi hỏi trong diễn đàn chính thức as well vì tôi đã chìm hơn một ngày vào điều này rồi. Nếu một giải pháp được đăng ở đó, tôi cũng sẽ đặt nó ở đây.)

Trả lời

23

Đây là những gì người dùng "BCD" qua tại các diễn đàn chính thức posted rằng kết thúc giải quyết vấn đề (với một sửa đổi nhỏ của bản thân mình để làm cho nó tĩnh để đưa vào một tập hợp các phương pháp hữu ích):

+ (UIImage *)scale:(UIImage *)image toSize:(CGSize)size 
{ 
    UIGraphicsBeginImageContext(size); 
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)]; 
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return scaledImage; 
} 
+0

Phiên bản của BCD là một danh mục trên 'UIImage', điều này có ý nghĩa hơn nhiều so với những gì tôi đã làm ở đây. – bbrown

+0

Cảm ơn bạn đã trả lời, hoạt động hoàn hảo –

0

Tôi không biết gì về cách Các tệp ico hoạt động, vì vậy có thể dễ dàng trích xuất hình ảnh 16x16 và sử dụng hình ảnh đó, nhưng tôi không biết làm cách nào.

Theo như tôi biết, bạn không thể đặt bất kỳ thuộc tính hữu ích nào trên hình ảnh theo kiểu chung UITableViewCell. Cách đơn giản nhất (vẫn lộn xộn, đặc biệt nếu bạn mới làm quen) để chia tỷ lệ mọi thứ xuống 16x16 sẽ là phân lớp UITableViewCell, đặt nó là UIImageView, luôn kích thước chế độ xem hình ảnh thành 16x16 và đặt contentMode thành UIViewContentModeAspectFit.

+0

Tôi đã thử phương pháp này và cách này không hiệu quả, nhưng có thể tôi đã làm sai. – bbrown

4

Tôi đang làm điều tương tự trong ứng dụng của mình.

UIImage* resizedImage(UIImage *inImage, CGRect thumbRect) 
{ 
    CGImageRef   imageRef = [inImage CGImage]; 
    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 

    if (alphaInfo == kCGImageAlphaNone) 
     alphaInfo = kCGImageAlphaNoneSkipLast; 

    CGContextRef bitmap = CGBitmapContextCreate (NULL, thumbRect.size.width, thumbRect.size.height, 8, thumbRect.size.width*3, 
                       CGColorSpaceCreateDeviceRGB(), alphaInfo); 

    CGContextDrawImage(bitmap, thumbRect, imageRef); 

    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage* result = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); 
    CGImageRelease(ref); 

    return result; 
} 

Sau đó, tạo hình ảnh mới hạn chế tỷ lệ. Thay thế "hình ảnh" bằng tệp ICO bạn nhận được từ Amazon.

CGRect sz = CGRectMake(0.0f, 0.0f, 16, 16); 
UIImage *resized = resizedImage(image, sz); 
+0

Vì lý do nào đó, mã của bạn đã ném rất nhiều lỗi CoreGraphics cho tôi. Nó có thể là một vấn đề với định dạng ICO. Đó là một câu trả lời tốt mặc dù. – bbrown

+1

Họ có biên dịch/lỗi liên kết không? Tôi không nghĩ rằng Xcode liên kết với khung CoreGraphics theo mặc định cho các dự án mới, do đó bạn sẽ cần thêm nó và câu lệnh @import tương ứng. –

+1

Vâng, bạn cần phải liên kết với khung công tác CoreGraphics. Nếu bạn không có đó là lý do tại sao bạn nhận được những lỗi đó. –

1

Không có đủ nghiệp để bình luận về câu trả lời, nhưng tôi đã thành công tốt với mã BBrandons ở trên.

Tôi đã nhận được một số cảnh báo hợp lý trên bảng điều khiển mặc dù liên quan đến byte cho mỗi cài đặt hàng không đủ cao - sau khi đọc câu trả lời cho số này post Tôi đã đặt nó thành 0, cho phép hệ thống xác định giá trị phù hợp.

ví dụ:

CGContextRef bitmap = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, CGColorSpaceCreateDeviceRGB(), alphaInfo); 
+0

Nếu bạn xác nhận 8 bit cho mỗi thành phần, đó là 1 byte cho mỗi thành phần. Câu trả lời của brandon ngăn 'kCGImageAlphaNone', vì vậy, đối với không gian màu RGB, luôn có bốn thành phần (ba màu, cộng với alpha). Đó là 1 × 4 = 4 byte cho mỗi pixel. Vì vậy, anh ta và bạn nên nhân rộng chiều rộng (pixel trên mỗi hàng) lên 4, không phải 3. Đi qua 0 không có tài liệu để làm việc, vì vậy bạn có lẽ không nên dựa vào nó và không nên sử dụng thủ thuật hoặc tệp đó lỗi tài liệu yêu cầu cho nó được ghi lại: https://bugreport.apple.com –

+0

Cảm ơn bạn đã mô tả các tính toán Peter, có nghĩa - Tôi cũng sẽ gửi một lỗi tài liệu cho tính toán tự động. – crafterm

1

Đây là cách tôi đã làm nó.Kỹ thuật này sẽ chăm sóc của di chuyển văn bản và văn bản chi tiết nhãn thích hợp sang trái:

@interface SizableImageCell : UITableViewCell {} 
@end 
@implementation SizableImageCell 
- (void)layoutSubviews { 
    [super layoutSubviews]; 

    float desiredWidth = 80; 
    float w=self.imageView.frame.size.width; 
    if (w>desiredWidth) { 
     float widthSub = w - desiredWidth; 
     self.imageView.frame = CGRectMake(self.imageView.frame.origin.x,self.imageView.frame.origin.y,desiredWidth,self.imageView.frame.size.height); 
     self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x-widthSub,self.textLabel.frame.origin.y,self.textLabel.frame.size.width+widthSub,self.textLabel.frame.size.height); 
     self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x-widthSub,self.detailTextLabel.frame.origin.y,self.detailTextLabel.frame.size.width+widthSub,self.detailTextLabel.frame.size.height); 
     self.imageView.contentMode = UIViewContentModeScaleAspectFit; 
    } 
} 
@end 

... 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[SizableImageCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 
    } 

    cell.textLabel.text = ... 
    cell.detailTextLabel.text = ... 
    cell.imageView.image = ... 
    return cell; 
} 
0

tôi đã sửa đổi người loại của người khác, để làm cho tất cả hình ảnh chiếm cùng một chiều rộng (chiều rộng có thể nhìn thấy), KHÔNG rộng:

-(UIImage*) centerImage:(UIImage *)inImage inRect:(CGRect) thumbRect 
{ 

    CGSize size= thumbRect.size; 
    UIGraphicsBeginImageContext(size); 
    //calculation 
    [inImage drawInRect:CGRectMake((size.width-inImage.size.width)/2, (size.height-inImage.size.height)/2, inImage.size.width, inImage.size.height)]; 
    UIImage *newThumbnail = UIGraphicsGetImageFromCurrentImageContext();   
    // pop the context 
    UIGraphicsEndImageContext(); 
    return newThumbnail; 
} 
Các vấn đề liên quan