What I do: I'm pretty new to Objective-C and I write an command-line-application on my old Macbook 2,1 that works with pictures.
My problem: I just want to get the width and height as a number (int, NSInteger, NSNumber, …) of a picture saved on my local hard-drive „Macintosh HD“.
Relevance for others: There must be a programatical way, to work with pictures. This is pretty basic.
My work platform: I'm developing on Mac OS X 10.6.8 with Xcode 3.2.6.
My research history: I already looked for cook-book-recipies and background-knowledge at stackoverflow and a few other sites to make my following trials, but I wasn't successful, yet. I present all I tried in the following. In advance, nothing worked.
//BildOeffner.h:
#import <Cocoa/Cocoa.h>
@interface BildOeffner : NSView
-(BildOeffner*) init;
- (NSNumber*) extrahiereBildBreite:(NSString*) bildPfad;
@end
//BildOeffner.m:
#import "BildOeffner.h"
@implementation BildOeffner
// extracts the image width
- (NSNumber*) extrahiereBildBreite:(NSString*) bildPfad{
NSBitmapImageRep* nsImageRep = [NSBitmapImageRep imageRepWithContentsOfFile:bildPfad];
NSInteger extrahierteBildBreite =[nsImageRep pixelsWide];
NSNumber* bildBreite = [NSNumber numberWithInt:extrahierteBildBreite];
return bildBreite;
}
@end
The code shows no compile-errors in the editor, but there are errors in the build-results: The Error-Message:
Ld build/Debug/FotobuchErsteller_0 normal x86_64
cd /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/gcc-4.2 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -L/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug -F/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug -filelist /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/Objects-normal/x86_64/FotobuchErsteller_0.LinkFileList -mmacosx-version-min=10.6 -framework Foundation -o /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug/FotobuchErsteller_0
Undefined symbols:
"_OBJC_CLASS_$_NSImage", referenced from:
objc-class-ref-to-NSImage in BildOeffner.o
"_OBJC_METACLASS_$_NSView", referenced from:
_OBJC_METACLASS_$_BildOeffner in BildOeffner.o
"_OBJC_CLASS_$_NSView", referenced from:
_OBJC_CLASS_$_BildOeffner in BildOeffner.o
"_OBJC_CLASS_$_NSBitmapImageRep", referenced from:
objc-class-ref-to-NSBitmapImageRep in BildOeffner.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
then I tried the following:
//BildAnalyst.h:
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
@interface BildAnalyst : NSObject
@property (assign) NSArray* bilderListe;
@property (assign) NSArray* bildObjektListe;
@property (assign) NSNumber* erwarteteBildHoehe;
@property (assign) NSNumber* erwarteteBildBreite;
-(BildAnalyst*) init;
-(BildAnalyst*) initWith:(NSArray*) neueBilderListe;
- (NSArray *)bilderListe;
- (void)setBilderListe:(NSArray *) neueBilderListe;
- (NSArray *)bildObjektListe;
- (void)setBildObjektListe:(NSArray *) neueBildObjektListe;
- (NSNumber*)erwarteteBildHoehe;
- (void)setErwarteteBildHoehe:(NSNumber*) neueErwarteteBildHoehe;
- (NSNumber*)erwarteteBildBreite;
- (void)setErwarteteBildBreite:(NSNumber*) neueErwarteteBildBreite;
- (void) erstelleListeAllerBilderImOrdner:(NSString*) absoluterPfadZumOrdner;
- (void) analysiereBilderListe;
@end
//BildAnalyst.m:
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import "BildAnalyst.h"
#import "Bild.h"
@implementation BildAnalyst
- (id)init {
self = [super init];
if (self){
self.bilderListe = nil;
self.erwarteteBildHoehe = [NSNumber numberWithInt:3024];
self.erwarteteBildBreite = [NSNumber numberWithInt:4032];
}
return self;
}
/*Der explizite Konstruktor dieser Klasse.
Parameter: NSMutableArray neueBilderListe
Rueckgabe: BildAnalyst bildAnalyst*/
-(BildAnalyst*) initWith:(NSMutableArray*) neueBilderListe{
self = [super init];
if (self){
self.bilderListe = neueBilderListe;
}
return self;
}
- (void) setBilderListe:(NSArray *) neueBilderListe{
self.bilderListe = neueBilderListe;
}
- (NSArray *) bilderListe{
return self.bilderListe;
}
- (void)setBildObjektListe:(NSArray *) neueBildObjektListe{
self.bildObjektListe = neueBildObjektListe;
}
- (NSArray *)bildObjektListe{
return self.bildObjektListe;
}
- (NSNumber*)erwarteteBildHoehe{
return self.erwarteteBildHoehe;
}
- (void)setErwarteteBildHoehe:(NSNumber*) neueErwarteteBildHoehe{
self.erwarteteBildHoehe = neueErwarteteBildHoehe;
}
- (NSNumber*)erwarteteBildBreite{
return self.erwarteteBildBreite;
}
- (void)setErwarteteBildBreite:(NSNumber*) neueErwarteteBildBreite{
self.erwarteteBildBreite = neueErwarteteBildBreite;
}
/* Die folgende Methode dient dem Auslesen eines Ordners und dem Speichern von darin enthaltenen Objekten in erster Hierarchieebene in ein Array, welches die Instanzvariable "bilderListe" befuellt.
Parameter NSString* absoluterPfadZumOrdner*/
- (void) erstelleListeAllerBilderImOrdner:(NSString*) absoluterPfadZumOrdner{
NSError* fehlerBeimLesenDesBilderordners;
NSFileManager* nsFileManager = [NSFileManager defaultManager];
[nsFileManager changeCurrentDirectoryPath:absoluterPfadZumOrdner];
NSArray* dateiListe = [nsFileManager contentsOfDirectoryAtPath:absoluterPfadZumOrdner error:&fehlerBeimLesenDesBilderordners];
[self setBilderListe:dateiListe];
}
/*Die folgende Methode dient der Analyse der Bilder, welche in einem Ordner gefunden wurden. Sie bestimmt das Bildformat und speichert die Bilder als Objekte in die Instanzvariable "bildObjektListe".
Parameter NSArray bilderListe*/
- (void) analysiereBilderListe {
NSUInteger i, count = [[self bilderListe] count];
NSMutableArray* neueBildObjektListe = [[NSMutableArray alloc] init];
for (i = 0; i < count; i++) {
NSString* bildPfad = [[self bilderListe] objectAtIndex:i];
NSBitmapImageRep* nsImageRep = [NSBitmapImageRep imageRepWithContentsOfFile:bildPfad];
NSInteger extrahierteBildHoehe = [nsImageRep pixelsHigh];
NSNumber* bildHoehe = [NSNumber numberWithInt:extrahierteBildHoehe];
NSInteger extrahierteBildBreite =[nsImageRep pixelsWide];
NSNumber* bildBreite = [NSNumber numberWithInt:extrahierteBildBreite];
Bild* bild = [[Bild alloc] init];
[bild setVollstaendigerBildName:bildPfad];
if ((bildHoehe == self.erwarteteBildHoehe) && (bildBreite == self.erwarteteBildBreite)) {
[bild setBildformat:hochformat];
} else if ((bildHoehe == self.erwarteteBildBreite) && (bildBreite == self.erwarteteBildHoehe)) {
[bild setBildformat:querformat];
} else if (bildHoehe ==bildBreite){
[bild setBildformat:quadratisch];
} else {
continue;
}
[neueBildObjektListe insertObject:bild atIndex:i];
}
self.bildObjektListe = neueBildObjektListe;
}
@end
with the class „Bild“:
//Bild.h:
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
typedef enum {hochformat, quadratisch, querformat} Bildformat;
@interface Bild : NSObject
@property (assign) NSString *vollstaendigerBildName;
@property (assign) Bildformat bildformat;
- (Bild*)init;
- (Bild*)init:(NSString *) bildName nunDasBildformat:(Bildformat)dasBildFormat;
- (void)setVollstaendigerBildName:(NSString *) neuerVollstaendigerBildName;
- (NSString *)vollstaendigerBildName;
- (void)setBildformat:(Bildformat) neuesBildformat;
- (Bildformat)bildformat;
@end
//Bild.m:
#import "Bild.h"
@implementation Bild
- (Bild*)init {
self = [super init];
if (self){
self.vollstaendigerBildName = @"";
self.bildformat = hochformat;
}
return self;
}
/*Der explizite Konstruktor dieser Klasse.
Parameter NSString bildName
Parameter Bildformat dasBildFormat
Rueckgabe Bild bild*/
- (Bild*)init:(NSString *)bildName nunDasBildformat:(Bildformat)dasBildFormat {
self = [super init];
if (self){
self.vollstaendigerBildName = bildName;
self.bildformat = dasBildFormat;
}
return self;
}
- (void) setVollstaendigerBildName:(NSString *) neuerVollstaendigerBildName{
self.vollstaendigerBildName = neuerVollstaendigerBildName;
}
- (NSString *) vollstaendigerBildName{
return self.vollstaendigerBildName;
}
- (void)setBildformat:(Bildformat) neuesBildformat{
self.bildformat = neuesBildformat;
}
- (Bildformat)bildformat{
return self.bildformat;
}
@end
The code shows no compile-errors in the editor, but there are errors in the build-results: The error-Message:
Ld build/Debug/FotobuchErsteller_0 normal x86_64
cd /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/gcc-4.2 -arch x86_64
-isysroot /Developer/SDKs/MacOSX10.6.sdk -L/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug
-F/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug
-filelist /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/Objects-normal/x86_64/FotobuchErsteller_0.LinkFileList -mmacosx-version-min=10.6
-framework Foundation -o /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug/FotobuchErsteller_0
Undefined symbols:
"_OBJC_CLASS_$_NSBitmapImageRep", referenced from:
objc-class-ref-to-NSBitmapImageRep in BildAnalyst.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
then I tried the following with the same class „BildAnalyst“:
I used
NSURL* nsUrl = [NSURL fileURLWithPath:bildPfad];
CIImage* nsImageRep = [CIImage imageWithContentsOfURL:nsUrl];
instead of
NSBitmapImageRep* nsImageRep = [NSBitmapImageRep imageRepWithContentsOfFile:bildPfad];
The code shows no compile-errors in the editor, but there are errors in the build-results: the error-Message:
Ld build/Debug/FotobuchErsteller_0 normal x86_64
cd /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0
setenv MACOSX_DEPLOYMENT_TARGET 10.6
/Developer/usr/bin/gcc-4.2 -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.6.sdk -L/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug -F/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug -filelist /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/Objects-normal/x86_64/FotobuchErsteller_0.LinkFileList -mmacosx-version-min=10.6 -framework Foundation -o /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug/FotobuchErsteller_0
Undefined symbols:
"_OBJC_CLASS_$_CIImage", referenced from:
objc-class-ref-to-CIImage in BildAnalyst.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
then I tried the following with the same class „BildAnalyst“:
I used
NSURL* nsUrl = [NSURL fileURLWithPath:bildPfad];
NSData* nsData = [NSData dataWithContentsOfURL:nsUrl];
UIImage* nsImageRep = [UIImage imageWithData:nsData];
instead of
NSBitmapImageRep* nsImageRep = [NSBitmapImageRep imageRepWithContentsOfFile:bildPfad];
The code shows compile-errors at the line with UIImage. The error-Messages:
CompileC build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/Objects-normal/x86_64/BildAnalyst.o BildAnalyst.m normal x86_64 objective-c com.apple.compilers.gcc.4_2
cd /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0
setenv LANG en_US.US-ASCII
/Developer/usr/bin/gcc-4.2 -x objective-c -arch x86_64 -fmessage-length=0 -pipe -std=gnu99
-Wno-trigraphs -fpascal-strings -fasm-blocks -O0 -Wreturn-type -Wunused-variable -isysroot /Developer/SDKs/MacOSX10.6.sdk -mfix-and-continue -mmacosx-version-min=10.6 -gdwarf-2
-iquote /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/FotobuchErsteller_0-generated-files.hmap
-I/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/FotobuchErsteller_0-own-target-headers.hmap
-I/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/FotobuchErsteller_0-all-target-headers.hmap -iquote /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/FotobuchErsteller_0-project-headers.hmap
-F/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug
-I/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/Debug/include
-I/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/DerivedSources/x86_64
-I/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/DerivedSources -include /var/folders/1J/1J8zfhnuH3Gk3T++j4sPBE+++TI/-Caches-/com.apple.Xcode.501/SharedPrecompiledHeaders/FotobuchErsteller_0_Prefix-gqjmlqmlzpuhpyfvtxjjyzqdlikg/FotobuchErsteller_0_Prefix.pch
-c /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m
-o /Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/build/FotobuchErsteller_0.build/Debug/FotobuchErsteller_0.build/Objects-normal/x86_64/BildAnalyst.o
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m: In function '-[BildAnalyst analysiereBilderListe]':
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:112: error: 'UIImage' undeclared (first use in this function)
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:112: error: (Each undeclared identifier is reported only once
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:112: error: for each function it appears in.)
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:112: error: 'nsImageRep' undeclared (first use in this function)
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:113: warning: unused variable 'bildHoehe'
/Users/Edo/Documents/FotobuchSkriptErsteller/FotobuchSkriptErsteller/FotobuchErsteller_0/BildAnalyst.m:104: warning:
unused variable 'neueBildObjektListe'
{standard input}:unknown:Undefined local symbol L_OBJC_CLASSLIST_SUP_REFS_$_0
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_0
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_1
{standard input}:unknown:Undefined local symbol L_OBJC_CLASSLIST_REFERENCES_$_1
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_2
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_3
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_4
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_5
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_6
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_7
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_8
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_9
{standard input}:unknown:Undefined local symbol L_OBJC_CLASSLIST_REFERENCES_$_2
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_10
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_11
{standard input}:unknown:Undefined local symbol L_OBJC_SELECTOR_REFERENCES_12
Has anybody a suggestion, what I can improve or perhaps another way? I just want to get the width and height of a picture saved on my local hard-drive „Macintosh HD“ as a number (int, NSInteger, NSNumber, ...).
Command-line tools, by default, link only against Foundation. You need to make sure your project is linked against the AppKit framework (or Cocoa, which automatically links to both Foundation or AppKit). Select your project in Xcode, select your target, and click on the "Build Phases" tab. In "Link Binary With Libraries", add AppKit. You should have access to AppKit classes such as
NSImage
.