ย้าย Blog
ย้ายไป Blog ใหม่นะครับ จะพยายามเขียนให้รู้เรื่องขึ้นครับ
http://tanseven-blog.blogspot.com/
ส่วน Entry เก่าๆ จะไล่ทำใหม่ให้ครับ
CoreData
วีธีการใช้ CoreData (ไม่ได้สร้าง Project with CoreData แต่เป็นการเพิ่มที่หลังนะครับ)
ทำการ Add CoreData.framework เข้าไปใน Project
Import Framework ใน ProjectName_Prefix.pch (ส่วนใหญ่อยู่ใน Other Sources)
#import <Availability.h>
#ifndef __IPHONE_3_0
// #warning “Projects that use Core Data only build using iPhone SDK 3.0 and later”
#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#endif
สร้าง File Data Model โดยเลือก Add -> New FIle เลือกที่ Resource -> Data Model
ออบแบบ Data Model (ใน File .xcdatamodel)
โดยเพิ่ม Class ในส่วนของ Entity (เครื่องหมาย +) แล้วตั้งชื่อ Class
และ Attribute ใน Property (เครื่องหมาย +) สำหรับ Attribute ต้องทำการกำหนดชนิดด้วย
หลังจากออกแบบ Data Model เสร็จแล้วให้ Add -> New File ใน Cocoa Touch Class เลือก Managed Object Class
ในหน้าที่ 3 ให้เลือก Class ที่ต้องการทำการ Generate Class จะได้ File Class.h และ Class.m มาใช้งาน
เข้าไปที่ File AppDelegate.h
ทำการเพิ่ม Property
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, readonly) NSString *applicationDocumentsDirectory;
AppDelegate.m
สร้าง Object ของ NSManagedObjectContext ใน
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
// Handle the error.
}
ใน Method
- (void)applicationWillTerminate:(UIApplication *)application;
เพิ่ม
NSError *error;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
// Handle the error.
}
}
ใน dealloc
[managedObjectContext release];
[managedObjectModel release];
[persistentStoreCoordinator release];
เพิ่ม Method ที่ทำงานเป็น Getter สำหรับ Property แต่ละตัวที่เพิ่มเข้าไป
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator: coordinator];
}
return managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];
return managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @”CoreDataName.sqlite”]];
NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
// Handle the error.
}
return persistentStoreCoordinator;
}
- (NSString *)applicationDocumentsDirectory {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
สร้าง MainViewController
ใน MainViewController.h สร้าง Property สำหรับเก็บข้อมูล และ NSManagedObjectContext
NSMutableArray *dataArray;
NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain) NSMutableArray *dataArray;
@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
ใน MainViewController.m
ทำ Synthesize Property
@synthesize dataArray, managedObjectContext;
การดึงข้อมูล (ถ้าไม่ต้องการ Sort ก็ไม่จำเป็นต้องใส่ส่วนของ NSSortDescriptor)
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@”name” ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
// Handle the error.
}
[self setDataArray:mutableFetchResults];
[mutableFetchResults release];
[request release];
การเพิ่มข้อมูล
Person *person = (Person *)[NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:managedObjectContext];
[person setName:@"Name"];
[person setSurname:@"Surname"];
NSError *error;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
[dataArray addObject:person];
การลบข้อมูล
NSManagedObject *personToDelete = [dataArray objectAtIndex:index];
[managedObjectContext deleteObject:personToDelete];
NSError *error;
if (![managedObjectContext save:&error]) {
// Handle the error.
}
[dataArray removeObjectAtIndex:index];
การแก้ไขข้อมูล
Person *p = (Person *)[dataArray objectAtIndex:index];
p.name = nameField.text;
p.surename = surenameField.text
if (![p.managedObjectContext save:&error]){
// Handle the error.
}
กลับไปที่ AppDelegate.m
#import “MainViewController.h”
ใน -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
สร้าง MainViewController แล้วกำหนด managedObjectContext
MainViewController *mainViewController = [[MainViewController alloc] init];
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
// Handle the error.
}
mainViewController.managedObjectContext = context;
[window addSubview:mainViewController.view];
[window makeKeyAndVisible];
[mainViewController.view release];
วิธีการ Filter ข้อมูลสร้าง Method (ใช้การดึงข้อมูล แต่มีการใช้ NSPredicate)
-(NSMutableArray *) filterObjectInContextEntityName:(NSString *)entityName predicate:(NSPredicate *)predicate sortKey:(NSString *)sortKey sortAscending:(BOOL) sortAscending managedObjectContext:(NSManagedObjectContext *)context{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[request setEntity:entity];
if (predicate != nil) {
[request setPredicate:predicate];
}
if (sortKey != nil) {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:sortKey ascending:sortAscending];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
[sortDescriptors release];
}
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[[managedObjectContext executeFetchRequest:request error:&error] mutableCopy] autorelease];
if (mutableFetchResults == nil) {
// Handle the error.
}
[request release];
return mutableFetchResults;
}
ตัวอย่างการใช้งาน
[self setDataArray:[self filterObjectInContextEntityName:@"Person" predicate:[NSPredicate predicateWithFormat:@"(surename == %@)", surenameField.text] sortKey:@”name” sortAscending:YES managedObjectContext:managedObjectContext]];
Custom TableViewCell
การออกแบบ TableCell ใน Table
ขั้นแรกสร้าง UITableView ขึ้นมาก่อน
หลังจากนั้นสร้าง File ใหม่โดย
Add -> New File -> Objective-C class ตรง Subclass of เลือก UITableViewCell
สร้าง Interface FIle (.xib) ออกแบบ UI
สร้าง Outlet กำหนด Property และทำ Synthesize
เข้าไปที่ FIle ViewController.m ที่มี UITableView
#import “MyTableViewCell.h”
ใน Method ของ DataSource
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
เราจะทำการสร้าง UITableViewCell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
NSArray *cellArray = [[NSBundle mainBundle] loadNibNamed:@”TableCell” owner:self options:nil];
for (int i = 0; i < [cellArray count]; ++i) {
id obj = [cellArray objectAtIndex:i];
if ([obj isKindOfClass:[MyTableViewCell class]]) {
cell = obj;
cell.cellLabel.text = [NSString stringWithFormat:@"%d", i];
cell.backgroungImage = [UIImage imageNamed:@"cellBackgroundImage.png"];
}
}
}
return cell;
}
การกำหนดความสูงของ TableViewCell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 100.0f;
}
UITableView (Basic)
วิธีทำ UITableView ใน iPhone
ใน iPhone เราจะพบ Application ที่ใช้ UITableView เป็นส่วนประกอบหลายตัว
วิธีทำในขั้นพื้นฐานก็ง่ายมากครับ
ขั้นแรกก็สร้าง UITableView แล้วกำหนด Delegate และ DataSource
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 300, 450) style:UITableViewStylePlain];
_tableView.delegate = self;
_tableView.dataSource = self;
สำหรับ UITableView จะมีส่วนของ Delegate และ DataSource ที่เราจำเป็นต้อง Implement ที่สำคัญ 3 ตัว
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath;
Method ที่จะทำงานเมื่อเราทำการเลือก Cell ใน Table ที่เราสร้างขึ้น
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath;
Method สำหรับการสร้าง Table Cell
-(NSInteger)tableView:(UITableView*)table numberOfRowsInSection:(NSInteger)section;
Method ที่จะบอกจำนวน Cell ของ Table
Example
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath{
NSLog(@”%@ :: %@”, indexPath, [_tableData objectAtIndex:indexPath.row] );
}-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@”cellIdentifier”] autorelease];
}
cell.textLabel.text = [_tableData objectAtIndex:indexPath.row];
return cell;
}
-(NSInteger)tableView:(UITableView*)table numberOfRowsInSection:(NSInteger)section{
return [_tableData count];
}
ในตัวอย่างจะใช้ NSArray _tableData เก็บข้อมูลของ Cell ใน Table ไว้นะครับ
เมื่อเลือกก็จะแสดง indexPath และข้อมูลออกมาครับ
*การประกาศตัวแปร การใช้ Delegate หาตัวอย่างได้ทั่วไปนะครับ (ในนี้จะไม่ได้ใส่ไว้)
NSString & NSData
สวัสดีครับ
วันนี้ก็จะเป็น เรื่องของ NSString และ NSData นะครับ
ซึ่งในการใช้งานบางทีเราอาจต้องมีการเล่นกับข้อมูล
NSString เป็นข้อมูลที่เราอ่านเข้าใจได้ แต่เราอาจต้องทำการแปลงข้อมูลนั้น
เพื่อนำไปให้คอมพิวเตอร์ใช้งาน ในบางครั้งเราจึงจำเป็นต้องแปลงข้อมูลจาก NSString เป็น NSData
หรืออาจจะต้องแปลง NSData เป็น NSString ซึ่งวิธีการก็ง่ายๆ ครับ
//NSString –> NSData
NSString *str = @”Hello”;
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
//NSData –> NSString
NSString *str2 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
แต่ถ้าจะอ่านจาก File ก็จะเป็นอีก Method ครับ
-(id)initWithContentsOfFile:(NSString *)path encoding:(NSStringEncoding)enc error:(NSError **)error
ส่วนที่เหลือลองอ่าน Doc ดูนะครับ…
ปรับ ScrollView ให้เลื่อนทีละครึ่งหน้า
สวัสดีครับ
หลังจากหัดเขียน iPhone ก็เจอปัญหากับ ScrollView
ต้องการให้เลื่อนที่ละครึ่งหน้า แต่เมื่อใช้ pagingEnabled เมื่อเลื่อน ScrollView Page จะเลื่อนที่ละหน้า…
พอลองทำก็เจอปัญหาหลายๆ อย่าง กระตุกบ้าง หยุดไม่ได้บ้าง
สุดท้ายก็ไปหาวิธีการได้ (จำเว็บไม่ได้)
สิ่งที่เราต้องทำคือ Implement Delegate Method ของ UIScrollView ที่ชื่อ
- (void) scrollViewDidScroll:(UIScrollView *)scrollView;
ซึ่งจะทำงานเมื่อเกิดการเลื่อน
ตัวอย่าง Code
สร้าง UIScrollView แล้วกำหนด pagingEnabled = YES ก่อนนะครับ
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat offset = scrollView.contentOffset.x / 2;
CGAffineTransform transform = CGAffineTransformMakeTranslation(offset, 0);
[_contentController.view setTransform:transform];
}
เมื่อเกิดการเลื่อนก็ให้ใช้ AffineTransform transform เลื่อนส่วนที่เป็น Content (ในี่นี้จะเลื่อนที่ละครึ่งหน้า)
หลังจากลองใช้งานดูก็พบว่ามีปัญหานิดหน่อยครับ
คือเมื่อ Paging ทำงานจำนวน Page จะถูกคำนวณไว้ ซึ่งทำให้เราเลื่อนได้เท่ากับจำนวนหน้าที่คำนวณไว้
จากตัวอย่างถ้า เราทำไว้ 10 หน้าแล้วให้เลื่อนไปทีละครึ่งหน้าเราจะไปได้แค่หน้าที่ 5
วิธีแก้ไขง่ายๆ คือเพิ่มขนาดของ ContentView ขึ่้น 2 เท่าเราก็จะสามารถเลื่อนได้จนหน้าสุดท้ายครับ
AsyncSocket
สวัสดีครับ
ตอนนี้มีโอกาสได้มาเขียน iPhone Application (ตอนนี้ยังมือใหม่อยู่ครับ…)
ได้เล่นลองใช้ Lib ชื่อ AsyncSocket (Download)
เป็น Lib สำหรับการส่งผ่านข้อมูลไปยัง Server โดยใช้ข้อมูล Host และ Port
สำหรับ Lib ตัวนี้ขั้นแรกต้องเพิ่ม Framework ก่อนนะครับ
Framework ที่เราต้องเพิ่มคือ CFNetwork.framework ครับ
มาเริ่มกันเลย
เริ่มจากการสร้าง Object ของ AsyncSocket
_asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];
หลังจากนั้นก็ทำการเชื่อมต่อนะครับ
NSError *err = nil;
[_asyncSocket connectToHost:_host onPort:_port error:&err];
ใส่ Domain (_host) และ Port (_port) ที่ใช้ในการเชื่อมต่อเข้าไปครับ (Function จะ Return BOOL กลับมาให้ครับ)
ซึ่งจะมี Delegate ที่ทำงานคือ
-(void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port;
ถ้าเกิดการ Disconnect เมื่อมี Error จะมี Delegate ที่ตอบสนองคือ
-(void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err;
และถ้าหากเราต้องการส่งข้อมูลนะครับ
[_asyncSocket writeData:_data withTimeout:TIMEOUT tag:0];
_data เป็น Object ของ NSData นะครับ TIMEOUT สามารถกำหนดได้ครับ
Delegate ที่ทำงานคือ
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag;
การรับข้อมูล
[sock readDataToData:[AsyncSocket CRLFData] withTimeout:TIMEOUT tag:0];
Delegate คือ
-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)aData withTag:(long)tag;
ผมก็พึ่งจะได้ลองใช้งานนะครับ
มีอะไรเพิ่มเติมก็ช่วยบอกด้วยครับ
ขอบคุณครับ…
ปล. ไม่ได้เขียน Blog มานานมากจำเครื่องมือไม่ได้แล้ว อ่านยากหน่อยนะครับ -_-”
ซื้อกล้องถ่ายรูปตัวแรกในชีวิต !!!
ไม่ได้เขียนมานานมาก (แต่ไม่มีคนอ่านอยู่แล้ว n_n)
เมื่อวันที่ 14 พค พึ่งไปซื้อกล้องถ่ายรูปมา
พอดีพี่เดฟไปร้านกล้องพอดี (ความรู้ไม่ค่อยมีเลยต้องหาคนช่วย)
ก็ซื้อ D90 18 – 105 VR Kit ของ Nikon
หลังจากซื้อกล้องถ่ายรูปเสร็จขากลับฝนดันตก -”-
แต่โชคดีหน่อยนึงที่ตอนมาถึงนครปฐมมันซ่าแล้ว
กลับบ้านมาก็รีบเอาออกมาแกะดูเลย (กลัวมันเปียก)
หลังจากเอาออกมาซักพักปรากฏว่า “ลืม“
ลืมซื้อที่เป่าฝุ่นกับสารกันชื้นมา…
แต่สารกันชื้นก่อนกลับไปซื้อโดโซะมา (ใช้แทนไปก่อน)
ก็ทำการประกอบเลนส์ เอาแบตออกมาชาร์จ
ตอนเช้าก็เอามาใส่ Mem ใส่ แบต แล้วยัดลงกระเป๋าไว้
วันเสาร์เย็นๆ ก็แบกกล้องถ่ายรูปออกไปร่อน (ลองหน่อย)
ก็ไปที่พระราชวังสนามจันทร์ (ไม่รู้จะไปไหนวนเวียนอยู่แถวนี้แหละ)
เข้าไปถึงก็เริ่มมั่วเลย (ความรู้ไม่มียังไม่ยอมอ่านคู่มืออีก -”-)
อันแรกเลย ถ่ายไปแล้วภาพมันไม่ชัดเท่าไหร่ พอดูแล้ว…
มันมี VR ให้ใช้ดันลืมเปิด…
ต่อมาเริ่มมั่วขึ้นอีก ปรับค่าไม่เป็นเริ่มงงกับ Mode ต่างๆ
ปรับยังไง หมุนเล่นลองดู -”- สุดท้ายใช้ที่มันมีอยู่แล้วนี่แหละ…
แล้วในหัวก็มีความคิดว่ากลับบ้านเอาคู่มือมันมาดูซักหน่อยเถอะ
วันอาทิตย์เย็น เอาหละมามั่วกันต่อ วันนี้อ่านคู่มือมานิดหน่อย
(ก็ยังงงอยู่ดีแหละ ไม่เคยหัดถ่ายรูปไม่ค่อยรู้เรื่อง)
วันนี้อ่านคู่มือมาแล้ว (นิดหน่อย Eng อ่อนแอ)
พอจะรู้วิธีปรับค่าแล้ว ^^ (ปรับไปทำไมก็ยังไม่ค่อยรู้)
ก็ถ่ายแบบมั่วๆ อีกวันถ่ายไปเรื่อยๆ ซักวันมันคงเป็นเอง…
แต่วันนี้ไม่ลืมเปิด VR นะแต่ภาพก็ยังไม่ค่อยชัดแฮะ
(ยังโฟกัสไม่ดี แล้วมือคงสั่นเกินรับไหว – -”)
วันนี้ท้องฟ้ามีขู่กันด้วย (แต่ถึงมันจะขู่ ก็ยังกลัวอะ)
วันนี้เลยกลับบ้านเร็วหน่อย
ส่วนรูปตอนนี้ยังไม่ได้เอารูปลงคอมอะนะ
(ที่จริงน่าจะลบทิ้งซะมากกว่า เก็บไว้ดูความห่วยของตัวเอง)
จากที่ไปลองถ่ายรูปมา 2 วันรู้สึกว่า อุปกรณ์มันดีนะ แต่คนถ่ายมันกาก…
ยังมีอะไรที่ต้องหัดอีกเยอะ หัดกันต่อไป.
Attachment_fu
สำหรับ Attachment_fu จะเป็น Plugin ของ Rails ที่ใช้สำหรับ Upload File นะครับ
โดยที่ตอนนี้จะเอามาใช้สำหรับ Upload ภาพ (ถ้าต้องการให้มีการทำ Image Processing เช่น การ Resize ภาพ ต้องทำการติดตั้ง Processor สำหรับการทำ Image Processing ก่อน เช่น rmagick)
ขั้นแรกก็ให้ Download Attachment_fu Plugin มาก่อน
หลังจากนั้นก็นำ Plugin ไปไว้ใน Project ที่ vendor/plugins
ส่วนการใช้งานก็เพิ่ม DB โดยจะประกอบด้วย
t.string :filename
t.string :path
t.string :content_type
t.integer :size
t.integer :width
t.integer :height
t.integer :parent_id
t.string :thumbnail
หลังจากนั้นก็ทำการบอก Model ให้รู้จักกับ Plugin
has_attachment :content_type => :image,
:storage => :file_system,
:min_size => 0,
:max_size => 1.megabytes,
:resize_to => ’640×480′,
:processor => ‘Rmagick’,
:thumbnails => { :medium => ’200×200′, :small => ’80×80′, :tiny => ’40×40′ }
ในที่นี้จะเป็นของภาพนะครับ โดยมีการใช้ Processor ของ Rmagick
การตรวจสอบก็สามารถใช้
validates_as_attachment
สำหรับการใช้งานในหน้า View ก็
ในการสร้าง (Upload) Files ให้ทำการเพิ่ม
:html => { :multipart => true }
เข้าไปใน form_for เช่น
<% form_for(@obj, :html => { :multipart => true }) do |f| %>
แล้วส่วนของ Select Image Field
<%= f.file_field ‘uploaded_data’ %>
ส่วนของหน้าในการ Show ให้ใช้
<%= image_tag(@obj.public_filename) %>
หรือ
<%= image_tag(@obj.public_filename(:medium)) %>
สำหรับภาพที่เป็น Medium (ตามที่ได้กำหนดไว้ใน Model)
ส่วนรายละเอียดอื่นๆ สามารถดูเพิ่มเติมได้ใน README ซึ่งจะมีคำอธิบายอยู่ด้วย
ติดตั้ง rmagick
ที่มา : Install RMagick on Mac OS X Leopard from Source
เริ่มจาก Download Source มาเก็บไว้ก่อน
ซึ่งในที่นี้ Source ที่จำเป็นก็จะมี
- freetype-2.3.5.tar.gz
- libpng-1.2.25.tar.gz
- jpegsrc.v6b.tar.gz
- tiff-3.8.2.tar.gz
- ghostscript-fonts-std-8.11.tar.gz
- ImageMagick.tar.gz
- rmagick.gem
ทำการแตกไฟล์ออกมาก่อนหลังจากนั้นก็เริ่มติดตั้งโดยใช้คำสั่งใน Terminal ที่
FreeType
cd freetype-2.3.5
./configure
make
sudo make install
cd ..
PNG Library
cd libpng-1.2.25
./configure
make
sudo make install
cd ..
JPEG Library
cd jpeg-6b
ln -s `which glibtool` ./libtool
export MACOSX_DEPLOYMENT_TARGET=10.5
./configure — enable-shared
make sudo make install
cd ..
(ถ้าไม่มี glibtool ต้องไปหามาติดตั้งนะครับ)
อย่าลืม –enable-shared ตอน Configure นะครับ
TIFF Library
cd tiff-3.8.2
./configure
make
sudo make install
cd ..
GhostScript Fonts
sudo mkdir /usr/local/share/ghostscript
sudo mv fonts /usr/local/share/ghostscript/fonts
ImageMagick
cd ImageMagick
export CPPFLAGS=-I/usr/local/include
export LDFLAGS=-L/usr/local/lib
./configure –disable-static –with-modules –without-perl –without-magick-plus-plus –with-quantum-depth=8 –with-gs-font-dir=/usr/local/share/ghostscript/fonts
cd..
RMagick
sudo gem install rmagick
ลองทดสอบ RMagick
irb
require’rmagick’
ถ้าขึ้นว่า true ก็แปลว่าลงสำเร็จแล้ว