Получить путь изображения из UIImage [дубликат]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

70
задан Alex Cio 26 November 2014 в 10:32
поделиться

16 ответов

неа. Вы не можете этого сделать.

Причина в том, что экземпляр UIImageView не хранит файл изображения. Он сохраняет отображение экземпляра UIImage. Когда вы делаете изображение из файла, вы делаете что-то вроде этого:

UIImage *picture = [UIImage imageNamed:@"myFile.png"];

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

Кроме того, даже если бы вы могли, вы никогда не получите информацию о имени файла из представления. Это нарушает MVC.

81
ответ дан Jonathan Sterling 18 August 2018 в 10:23
поделиться
  • 1
    Просто потому, что он прерывает MVC, это не значит, что вы не должны этого делать. В конце концов, правила должны быть сломаны;) – Sneakyness 17 December 2009 в 23:30
  • 2
    Некоторые правила. Но на iPhone и Mac вы всегда должны делать все возможное, чтобы придерживаться MVC. Они упрямые. – Jonathan Sterling 19 December 2009 в 02:21
  • 3
    На самом деле это можно сделать, но для редактирования imageNamed требуется привинчивание с Objective-C runtime (да, нарушение правил lots ). Если вы действительно должны сделать это в своем проекте для некоторых важных причина, см. мой ответ ниже. – Ben Gotow 24 December 2012 в 08:22
  • 4
    @JonathanSterling существует много разных интерпретаций MVC – abbood 28 May 2013 в 08:10
  • 5
    Похоже, UIImage (названный: String) в Swift – RedEagle2000 4 August 2015 в 16:30

Swift 3

Сначала установите идентификатор accessibilityIdentifier как imageName

myImageView.image?.accessibilityIdentifier = "add-image"

Затем используйте следующий код.

extension UIImageView
{
func getFileName() -> String? {
    // First set accessibilityIdentifier of image before calling.
    let imgName = self.image?.accessibilityIdentifier
    return imgName
}
}

Наконец, способ вызова метода для идентификации

myImageView.getFileName()
1
ответ дан Abdul Hameed 18 August 2018 в 10:23
поделиться

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

  • Создайте категорию с вашей собственной реализацией +imageNamed:(NSString*)imageName, которая обращается к существующей реализации и использует описанную здесь технику ( Как использовать objc_setAssociatedObject / objc_getAssociatedObject внутри объекта? ), чтобы окончательно связать imageName с возвращаемым объектом UIImage.
  • Использовать метод Swizzling для замены предоставленной реализации imageNamed: для вашей реализации в таблице поиска метода в среде выполнения Objective-C.
  • Доступ к имя, связанное с экземпляром UIImage (с использованием objc_getAssociatedObject) в любое время.

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

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

15
ответ дан Community 18 August 2018 в 10:23
поделиться
  • 1
    Почему бы вам просто не создать подкласс UIImage для переопределения метода? – vrwim 21 March 2015 в 17:33
  • 2
    vrwim: вам нужно swizzle, когда вы хотите добавить что-то к существующему поведению. если вы будете использовать категорию (или наследование), вы сможете переключать некоторый код в другой, но вы не сможете этого сделать, не теряя первоначального поведения. другими словами, если вы попытаетесь написать (в унаследованном классе): +imageNamed:(NSString*)imageName { // save file name in new property or whatever [self imageNamed:imageName]; // infinite loop [super imageNamed:imageName]; // super doesn't contain such a method } – yonivav 30 December 2015 в 11:02
  • 3
    hi ben любая причина не просто использовать setAccessibilityIdentifier, как предложено nizar ahmed? – Crashalot 4 May 2016 в 14:26

Я имею дело с этой проблемой, я решил ее с помощью шаблона проектирования MVC, я создал класс карты:

@interface Card : NSObject

@property (strong,nonatomic) UIImage* img;

@property  (strong,nonatomic) NSString* url;

@end

// затем в UIViewController в DidLoad Method to Do:

// init Cards
Card* card10= [[Card alloc]init];
card10.url=@"image.jpg";  
card10.img = [UIImage imageNamed:[card10 url]];

// для примера

UIImageView * myImageView = [[UIImageView alloc]initWithImage:card10.img];
[self.view addSubview:myImageView];

// вы можете проверить имя изображения, чтобы вы могли сделать это:

// например

 NSString * str = @"image.jpg";

 if([str isEqualToString: [card10 url]]){
 // your code here
 }
0
ответ дан Dharmesh Dhorajiya 18 August 2018 в 10:23
поделиться

Да, вы можете сравнить с помощью таких данных, как ниже код

UITableViewCell *cell = (UITableViewCell*)[self.view viewWithTag:indexPath.row + 100];

UIImage *secondImage = [UIImage imageNamed:@"boxhover.png"];

NSData *imgData1 = UIImagePNGRepresentation(cell.imageView.image);
NSData *imgData2 = UIImagePNGRepresentation(secondImage);

BOOL isCompare =  [imgData1 isEqual:imgData2];
if(isCompare)
{
    //contain same image
    cell.imageView.image = [UIImage imageNamed:@"box.png"];
}
else
{
    //does not contain same image
    cell.imageView.image = secondImage;
}
1
ответ дан Hardik Mamtora 18 August 2018 в 10:23
поделиться
if ([imageForCheckMark.image isEqual:[UIImage imageNamed:@"crossCheckMark.png"]]||[imageForCheckMark.image isEqual:[UIImage imageNamed:@"checkMark.png"]])
{

}
9
ответ дан iEinstein 18 August 2018 в 10:23
поделиться
  • 1
    В случае, если условие я просто проверяю имя изображения – iEinstein 19 February 2013 в 13:37
  • 2
    Кодовые ответы не так полезны. Добавьте короткий текст, объясняющий, что делает ваш фрагмент кода. – nalply 19 February 2013 в 13:44
  • 3
    если условие соответствует совпадению имени изображения в imageForCheckMark и [UIImage imageNamed: @ "crossCheckMark.png & quot;]], если true, то выполните некоторую строку кода, иначе другую строку кода – iEinstein 19 February 2013 в 15:32
  • 4
    Спасибо, чувак, очень хорошо. – ΩlostA 25 September 2016 в 01:09

вы можете использовать метод setAccessibilityIdentifier для любого подкласса UIView

UIImageView *image ;
[image setAccessibilityIdentifier:@"file name"] ;

NSString *file_name = [image accessibilityIdentifier] ;
94
ответ дан j0k 18 August 2018 в 10:23
поделиться
  • 1
    я наткнулся здесь просто b / c, я создаю приложение с локализованными изображениями .. и я хочу создать метод localize, который просто проходит через изображения и делает некоторое регулярное выражение на имени изображения (у меня есть очень веские причины чтобы сделать эти изображения реальными изображениями, а не создавать пользовательский UIImage). Мне было интересно, был ли более чистый способ локализации изображений в объективе c .., поскольку все говорят о MVC, а что нет – abbood 19 August 2014 в 11:59
  • 2
    Я знаю, что с MVC нет в порядке, но мне это нужно для тестирования. – Radek Wilczak 5 November 2014 в 08:30
  • 3
    Для использования OSX accessibilityDescription – Anoop Vaidya 18 February 2015 в 13:54
  • 4
    есть ли технический недостаток этого решения? это похоже на самое простое, чистое решение, так почему же он не считается принятым ответом? – Crashalot 4 May 2016 в 14:27

неа. Невозможно сделать это изначально. Вам придется подклассифицировать UIImageView и добавить свойство imageFileName (которое вы устанавливаете при настройке изображения).

9
ответ дан Kenny Winker 18 August 2018 в 10:23
поделиться
  • 1
    hi kenny любая причина не просто использовать setAccessibilityIdentifier, как было предложено nizar ahmed? – Crashalot 4 May 2016 в 14:26

Вы можете использовать функцию объектива c Runtime для сопоставления imagename с UImageView.

Сначала импортируйте #import <objc/runtime.h> в свой класс

, затем выполните свой код, как показано ниже:

NSString *filename = @"exampleImage";
UIImage *image = [UIImage imagedName:filename];
objc_setAssociatedObject(image, "imageFilename", filename, OBJC_ASSOCIATION_COPY);
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
//You can then get the image later:
NSString *filename = objc_getAssociatedObject(imageView, "imageFilename");

Надеюсь, это вам поможет.

3
ответ дан Meet Doshi 18 August 2018 в 10:23
поделиться
  • 1
    возвращает null! ... – Mc.Lover 30 August 2014 в 20:31
  • 2
    да его возврат null ... – Kishore Kumar 25 February 2016 в 14:04
  • 3
    Да Возврат (null) – Nilesh 23 April 2016 в 11:42
  • 4
    Он вернет null, потому что вы еще не установили идентификатор accessibilityIdentifier. Установите его так [image setAccessibilityIdentifier:@"demoFileName.png"] ;, а затем вызовите этот метод – NSNoob 11 July 2016 в 10:20
  • 5
    Консоль говорит: error: свойство 'accessibilityIdentifier' не найдено на объекте типа 'UIImage *' - Xcode 8.1 – Jamal Zafar 29 November 2016 в 12:38

Ни UIImageView, ни UIImage не сохраняются в имени файла загруженного изображения.

Вы можете либо

1: (как было предложено Kenny Winker выше) подкласса UIImageView иметь файлName свойство или

2: назовите файлы изображений с цифрами (image1.jpg, image2.jpg и т. д.) и пометьте эти изображения соответствующим номером (tag = 1 для image1.jpg, tag = 2 для image2. jpg и т. д.) или

3: Имейте переменную уровня класса (например, NSString * currentFileName), которая обновляется всякий раз, когда вы обновляете образ UIImageView

7
ответ дан Mihir Mathuria 18 August 2018 в 10:23
поделиться

Код работает в swift3 - писать код внутри метода didFinishPickingMediaWithInfo:

if let referenceUrl = info[UIImagePickerControllerReferenceURL] as? 

NSURL {

  ALAssetsLibrary().asset(for: referenceUrl as URL!, resultBlock: { asset in

    let fileName = asset?.defaultRepresentation().filename()
    print(fileName!)

    //do whatever with your file name            
    }, failureBlock: nil)
}
-1
ответ дан Niraj Paul 18 August 2018 в 10:23
поделиться

использовать ниже

 UIImageView *imageView = ((UIImageView *)(barButtonItem.customView.subviews.lastObject));
 file_name = imageView.accessibilityLabel;
-1
ответ дан Nischal Hada 18 August 2018 в 10:23
поделиться

Не существует собственного способа сделать это; однако вы можете легко создать это поведение.

Вы можете подклассы UIImageView и добавить новую переменную экземпляра:

NSString* imageFileName;

Тогда вы можете переопределить setImage, первая настройка imageFileName в имя файла изображения, которое вы устанавливаете, а затем вызывается [super setImage:imageFileName]. Что-то вроде этого:

-(void) setImage:(NSString*)fileName
{
   imageFileName = fileName;
   [super setImage:fileName];
}

Просто потому, что это невозможно сделать изначально не означает, что это невозможно:)

10
ответ дан sth 18 August 2018 в 10:23
поделиться
  • 1
    Спасибо за то, что вы сделали это и помогли сохранить сайт чистым! – Josh Caswell 22 May 2012 в 03:58

Или вы можете использовать идентификатор восстановления, например:

let myImageView = UIImageView()
myImageView.image = UIImage(named: "anyImage")
myImageView.restorationIdentifier = "anyImage" // Same name as image's name!

// Later, in UI Tests:
print(myImageView.restorationIdentifier!) // Prints "anyImage"

В основном в этом решении вы используете идентификатор восстановления для хранения имени изображения, чтобы вы могли использовать его позже в любом месте. Если вы обновите изображение, вы также должны обновить идентификатор восстановления, например:

myImageView.restorationIdentifier = "newImageName"

Надеюсь, это поможет вам, удачи!

1
ответ дан ThiagoAM 18 August 2018 в 10:23
поделиться
3
ответ дан Meet Doshi 6 September 2018 в 22:41
поделиться
3
ответ дан Meet Doshi 30 October 2018 в 03:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: