【问题标题】:How to get a UIImage's image as an NSString?如何将 UIImage 的图像作为 NSString 获取?
【发布时间】:2012-09-09 17:35:50
【问题描述】:

我需要获取 UIImage 图像的值作为字符串。

以前我在做:

if(images[imageNo].image == [UIImage imageNamed:@"image1.png"])
{

但现在我有更多的条件,所以我想使用一个开关,做:

switch(images[imageNo].image)
{
    case @"image1.png":
    break;
}

有没有办法做到这一点?谢谢!

【问题讨论】:

  • 这与Xcode无关,重新标记。
  • 对不起。我会尽量不要再打错标签。
  • 您能否详细说明“作为字符串的 UIImage 图像的值”是什么意思?
  • 我认为您问错了问题 - 为什么不在程序 (MVC) 的“模型”中处理对象身份?

标签: ios cocoa-touch nsstring uiimage


【解决方案1】:

嗯,我不确定你想在这里完成什么,但使用[UIImage imageNamed:@"image1.png"],绝对是一种非常糟糕的比较方法,因为你正在无缘无故地创建一个新的 UIImage 对象,而且你是当你应该使用 isEqual 时使用 == 运算符,因为它们是对象。

我相信您想要做的是将其转换为 base 64 字符串?如果是这样,您可以使用它:

NSData *imageData = UIImageJPEGRepresentation(myImage, 1.0);

NSString *encodedString = [imageData base64Encoding];

【讨论】:

  • 动态生成数据表示也非常昂贵。
  • “您正在动态创建一个新的 UIImage 对象” - 实际上,不,OP 很幸运,因为该方法使用缓存。但是,这种未记录的行为仍然不可靠。
【解决方案2】:

H2C03提供的答案是合适的。使用字典来关联名称。

但是,另一种方法是使用关联对象。请注意,使用关联对象在空间和时间上都有成本,但它们仅适用于这种情况(添加类别属性)。

@interface UIImage (MyImageLabel)
@property (nonatomic, copy) NSString *label;
@end


#import <objc/runtime.h>
@implementation UIImage (MyImageLabel)
static char const kImageLabelKey[1];
- (NSString*)label {
    return objc_getAssociatedObject(self, kImageLabelKey);
}
- (void)setLabel:(NSString *)label {
    objc_setAssociatedObject(self, kImageLabelKey, label, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
@end

现在,您可以在 UIImage 实例上拥有一个 label 属性,如下所示:

myImage.label = someLabelStringCouldEvenBeFilename;

if ([myImage.label isEqualToString:someString]) {
}

典型的警告适用于类别中的任何内容。大多数人会鼓励您使用唯一的前缀或后缀来区分您的类别方法与未来潜在的 Apple 名称。

请注意,您可以向类别添加其他方法,如下所示...

+ (UIImage)myImageNamed:(NSString*)name {
    id result = [self imageNamed:name];
    [result setLabel:name];
    return result;
}

现在你会自动设置标签。

当然,如果您将始终创建自己的图像,并且避免与关联对象相关联的“肮脏”(尽管您的所有图像都需要是 MyUIImages),那么您可以将其作为子类来执行。

@interface MyUIImage : UIImage
@property (nonatomic, copy) NSString *label;
@end

@implementation MyUIImage
// Now, you override imageNamed:
+ (UIImage*)imageNamed:(NSString*)name {
    UIImage *image = [super imageNamed:name];
    self.label = name;
    return image;
}
@end

【讨论】:

    【解决方案3】:

    您的两种方法都不正确。第一个依赖于缓存(未记录),同时第二个是语法错误 - 'case' 关键字需要一个编译时常量表达式。

    据我所知,iOS SDK 中没有这样的方法可以返回图像的文件名——仅仅是因为它不是图像的属性(对于以编程方式创建的图像会返回什么?)。您应该尝试对 NSDictionary 进行操作,将与文件名关联的 UIImage 对象存储为键,并使用 isEqualToString: 比较键。

    所以你应该只创建一次图像,并将它们存储在字典中:

    // assuming `images` is an already created instance variable of your class
    [images setObject:[UIImage imageNamed:@"ImgOne.png"] forKey:@"ImgOne.png"];
    // and so on, with every image you need
    
    // then once you have to check against a file name, use:
    UIImage *img = [images objectForKey:@"FileName.png"];
    if ([someImage isEqual:img]) {
        // you can now be sure that the image set to the object was once named "FileName"
    }
    

    【讨论】:

    • 请您稍微扩展一下。我对 XCode 开发相当陌生,从未使用过 NSDictionary。谢谢!
    • @user1401690 当然,等一下。 (同样,它更像是 iOS 开发 :) 我在没有 Xcode 的情况下完成所有 iOS 编程。)
    • 谢谢,效果很好,但是在 NSDictionary 中使用这种方法而不是 NSArray 有什么好处吗?它们看起来非常相似。
    • @user1401690 你将如何将密钥存储在数组中并保持它们与图像的关联?
    • 哦,对不起;我实际上最终使用了 NSArray 而不是 NSDictionary。但是您的回答启发了我,我会再次将其标记为正确,因为它是最接近的答案。
    猜你喜欢
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2012-10-19
    • 2012-05-03
    • 1970-01-01
    • 2014-09-26
    相关资源
    最近更新 更多