QR-коды сегодня используются практически везде, где только можно себе представить. Вполне очевидно, что многим разработчикам было бы интересно узнать, как организовать сканирование и распознавание QR-кодов в своих приложениях для мобильных устройств.
В процессе разработки собственного приложения для iOS столкнулся с тем, что информации на русском языке по теме обработки QR-кодов на просторах Интернета крайне мало. Разобравшись с самим приложением, решил, что необходимо исправить эту вопиюще несправедливую ситуацию. Под катом Вы найдете описание процесса разработки крайне простого приложения, распознающего QR-коды, и представляющего интерес для начинающих iOS-разработчиков. Данная заметка предполагает наличие базовых знаний особенностей работы в Xcode и программирования под iOS.
Разработка будет вестись для Xcode 4.1, для более ранних версий Xcode (начиная с версии 3.2.3) процесс будет практически аналогичным.
Задача сканирования и распознавания образов, вообще говоря, является достаточно сложной с точки зрения математической и технической реализации. Иными словами, разработать «с нуля» приложение, распознающее штрих-код или QR-код, достаточно сложно. К счастью для нас прогресс не стоит на месте и большую часть сложной работы по сканированию и распознаванию уже кто-то когда-то решил. Чем мы и воспользуемся.
Итак, для работы Вам потребуется:
Поскольку эмулятор iOS устройств, распространяемый с Xcode, не умеет эмулировать камеру, для тестирования приложения нам потребуется реальное устройство – iPhone, iPod Touch или iPad 2, т.е. любое устройство с камерой, выпущенное в течение последних 2 лет вполне себе подойдет.
Также для работы мы будем использовать SDK для сканирования и распознавания QR-кодов, который возьмет на себе обработку графического изображения QR-кода и его преобразование в текстовую информацию. Существуют несколько готовых open-source библиотек, предлагающих подобный функционал, мы будем использовать SDK ZBar iPhone SDK версии 1.2 (подойдет и версия выше 1.2), скачать которую можно тут.
По указанной ссылке Вы скачаете образ ZBarSDK-1.2.dmg, внутри которого нас будет интересовать папка ZBarSDK, в которой и содержится нужная нам библиотека.
Итак, приступим.
1. Запустим Xcode, создадим в нем новый проект «View-based Application», назовем его QR Scanner, и сохраним его где-нибудь в удобном для Вас месте на диске.
2. В Project navigator откроем QR_ScannerViewController.xib.
3. Разместим на форме Round Rect Button и разместим на ней, например, текст «Сканировать QR-код».
4. Разместим в верхней части формы элемент Image View, установим в Инспекторе объектов свойство view mode в Aspect Fit.
5. Разместим в нижней части формы элемент Text View, уберем текст-заглушку, вместо него разместим, например, текст «Для начала сканирования QR-кода нажмите на кнопку в нижней части экрана». Снимем в Инспекторе объектов галочку User Interaction Enabled.
6. Добавим аутлеты в код контроллера, для этого откроем QR_ScannerViewController.h и приведем его к такому виду:
Как видно из кода, мы объявили два аутлета на элементы управления UITextView и UIImageView, которые мы разместили на нашей форме. Кроме этого, мы объявили IBAction, который будет обрабатывать нажатие нашей кнопки и сканировать QR-код.
7. Откроем QR_ScannerViewController.xib и свяжем созданные нами аутлеты и действие scanButtonTapped с соответствующими элементами формы:
8. Теперь нам надо создать реализацию объявленных в заголовочном файле класса QR_ScannerViewController объектов. Откроем файл QR_ScannerViewController.m и приведем его к следующему виду:
Если Вы не слишком хорошо знакомы с разработкой приложений в Xcode, не пугайтесь – большую часть кода среда разработки добавила в этой файл сама. Мы всего лишь реализовали объявленные в заголовочном файле объекты и действие:
Кроме того, мы добавили код для освобождения аутлетов при выгрузке формы из памяти (viewDidUnload):
Также освобождаем память в dealloc:
9. Теперь нам необходимо непосредственно включить в наше приложение скаченную ранее библиотеку ZBarSDK. Для этого откроем образ диска ZBarSDK-1.2.dmg, найдем в нем папку ZBarSDK и перетащим ее из Finder в свой проект в Xcode.
10. Далее нам необходимо добавить несколько дополнительных библиотек в наш проект. В свойствах Target нашего проекта откроем вкладку Build Phases, раскроем выпадающий список Link Binary With Libraries и нажимая на плюсик в нижней левой части этого списка добавим следующие библиотеки:
11. Импортируем заголовочный файл нашего SDK. Для этого откроем файл «QR Scanner-Prefix.pch» и добавим в него строчку:
12. Для нашего класса контроллера QR_ScannerViewController объявим поддержку протокола делегата <ZBarReaderDelegate>, для этого в файле QR_ScannerViewController.h поправим объявление класса:
13. Теперь мы полностью готовы к тому, чтобы заставить приложение начать делать что-то полезное. В файле QR_ScannerViewController.m изменим код scanButtonTapped на следующий:
Теперь после нажатия на кнопку в приложении будет вызываться этот метод, который будет непосредственно вызывать представление, на котором будет отображаться картинка с камеры. Пользователю достаточно будет навести камеру на QR-код, после чего он будет считан и обработан.
14. Однако считать и обработать QR-код мало, надо еще показать пользователю результаты обработки. Для этого нам необходимо реализовать следующий метод делегата (все в том же QR_ScannerViewController.m):
После работы этого метода с экрана будет убрано представление, фотографировавшее QR-код и показано исходное представление, разработанное нами в файле QR_ScannerViewController.xib. На этом представлении можно будет увидеть фото QR-кода и текст этого QR-кода.
15. Вот и все! Далее сохраняем проект, компилируем, запускаем на устройстве.
16. Для сканирования QR-кода необходимо нажать на кнопку «Сканировать QR-код» и навести камеру на изображение QR-кода. Программа автоматически «узнает» QR-код, сфотографирует его и распознает, после чего выведет содержащуюся в нем информацию на экран.
Описание процесса запуска приложений на устройстве мы оставили за кадром, т.к., во-первых, это достаточно долгий с точки зрения описания процесс, а, во-вторых, эта статья предполагает наличие у читателя некоторой информационной базы в части работы с Xcode, что неявно предполагает умение запускать разработанные приложения на физическом устройстве. Тем не менее, если у читателей возникнет желание, могу описать процесс организации запуска разработанных приложений на физическом устройстве в отдельной заметке.
Отмечу также, что использованная нами библиотека позволяет распознавать не только QR-коды, но и многие другие виды двухмерных кодов. Мы умышленно исключили из рассмотрения этот функционал, чтобы сконцентрироваться на задаче распознавания QR-кодов, а также чтобы стимулировать самостоятельное изучение данной библиотеки теми, кого она заинтересует.
В заключение несколько полезных ссылок по теме данной заметки:
1. Сайт разработчиков библиотеки ZBarSDK.
2. Википедия о QR-кодах
В процессе разработки собственного приложения для iOS столкнулся с тем, что информации на русском языке по теме обработки QR-кодов на просторах Интернета крайне мало. Разобравшись с самим приложением, решил, что необходимо исправить эту вопиюще несправедливую ситуацию. Под катом Вы найдете описание процесса разработки крайне простого приложения, распознающего QR-коды, и представляющего интерес для начинающих iOS-разработчиков. Данная заметка предполагает наличие базовых знаний особенностей работы в Xcode и программирования под iOS.
Разработка будет вестись для Xcode 4.1, для более ранних версий Xcode (начиная с версии 3.2.3) процесс будет практически аналогичным.
Задача сканирования и распознавания образов, вообще говоря, является достаточно сложной с точки зрения математической и технической реализации. Иными словами, разработать «с нуля» приложение, распознающее штрих-код или QR-код, достаточно сложно. К счастью для нас прогресс не стоит на месте и большую часть сложной работы по сканированию и распознаванию уже кто-то когда-то решил. Чем мы и воспользуемся.
Итак, для работы Вам потребуется:
- Mac OS X >= 10.6.x (Snow Leopard), у меня, соответственно, 10.7.2 Lion.
- Xcode >= 3.2.3, я работал в версии 4.1.
- iPhone >= 3GS, я тестировал на iPhone 3GS и iPad 2.
- iOS 4.0 и выше на устройстве (на самом деле, можно и 3.1).
- Учетная запись iOS-разработчика, т.к. без нее нельзя тестировать разработанные приложения на физических устройствах.
Поскольку эмулятор iOS устройств, распространяемый с Xcode, не умеет эмулировать камеру, для тестирования приложения нам потребуется реальное устройство – iPhone, iPod Touch или iPad 2, т.е. любое устройство с камерой, выпущенное в течение последних 2 лет вполне себе подойдет.
Также для работы мы будем использовать SDK для сканирования и распознавания QR-кодов, который возьмет на себе обработку графического изображения QR-кода и его преобразование в текстовую информацию. Существуют несколько готовых open-source библиотек, предлагающих подобный функционал, мы будем использовать SDK ZBar iPhone SDK версии 1.2 (подойдет и версия выше 1.2), скачать которую можно тут.
По указанной ссылке Вы скачаете образ ZBarSDK-1.2.dmg, внутри которого нас будет интересовать папка ZBarSDK, в которой и содержится нужная нам библиотека.
Итак, приступим.
1. Запустим Xcode, создадим в нем новый проект «View-based Application», назовем его QR Scanner, и сохраним его где-нибудь в удобном для Вас месте на диске.
2. В Project navigator откроем QR_ScannerViewController.xib.
3. Разместим на форме Round Rect Button и разместим на ней, например, текст «Сканировать QR-код».
4. Разместим в верхней части формы элемент Image View, установим в Инспекторе объектов свойство view mode в Aspect Fit.
5. Разместим в нижней части формы элемент Text View, уберем текст-заглушку, вместо него разместим, например, текст «Для начала сканирования QR-кода нажмите на кнопку в нижней части экрана». Снимем в Инспекторе объектов галочку User Interaction Enabled.
6. Добавим аутлеты в код контроллера, для этого откроем QR_ScannerViewController.h и приведем его к такому виду:
#import <UIKit/UIKit.h>
@interface QR_ScannerViewController : UIViewController {
UITextView *resultText;
UIImageView *resultImage;
}
@property (nonatomic, retain) IBOutlet UIImageView *resultImage;
@property (nonatomic, retain) IBOutlet UITextView *resultText;
- (IBAction)scanButtonTapped;
@end
Как видно из кода, мы объявили два аутлета на элементы управления UITextView и UIImageView, которые мы разместили на нашей форме. Кроме этого, мы объявили IBAction, который будет обрабатывать нажатие нашей кнопки и сканировать QR-код.
7. Откроем QR_ScannerViewController.xib и свяжем созданные нами аутлеты и действие scanButtonTapped с соответствующими элементами формы:
- Аутлет resultImage свяжем с элементом ImageView.
- Аутлет resultText свяжем с элементом TextView.
- Действие scanButtonTapped свяжем с событием TouchUpInside кнопки Round Rect Button.
8. Теперь нам надо создать реализацию объявленных в заголовочном файле класса QR_ScannerViewController объектов. Откроем файл QR_ScannerViewController.m и приведем его к следующему виду:
#import "QR_ScannerViewController.h"
@implementation QR_ScannerViewController
@synthesize resultImage;
@synthesize resultText;
- (IBAction)scanButtonTapped{
NSLog(@"Now we are scanning QR-code...");
}
- (void)didReceiveMemoryWarning
{ [super didReceiveMemoryWarning];}
- (void)viewDidUnload
{
[super viewDidUnload];
self.resultText = nil;
self.resultImage = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{ return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);}
- (void) dealloc {
[resultImage release];
[resultText release];
[super dealloc];
}
Если Вы не слишком хорошо знакомы с разработкой приложений в Xcode, не пугайтесь – большую часть кода среда разработки добавила в этой файл сама. Мы всего лишь реализовали объявленные в заголовочном файле объекты и действие:
@synthesize resultImage;
@synthesize resultText;
- (IBAction)scanButtonTapped{
NSLog(@"Now we are scanning QR-code...");
}
Кроме того, мы добавили код для освобождения аутлетов при выгрузке формы из памяти (viewDidUnload):
self.resultText = nil;
self.resultImage = nil;
Также освобождаем память в dealloc:
[resultImage release];
[resultText release];
9. Теперь нам необходимо непосредственно включить в наше приложение скаченную ранее библиотеку ZBarSDK. Для этого откроем образ диска ZBarSDK-1.2.dmg, найдем в нем папку ZBarSDK и перетащим ее из Finder в свой проект в Xcode.
10. Далее нам необходимо добавить несколько дополнительных библиотек в наш проект. В свойствах Target нашего проекта откроем вкладку Build Phases, раскроем выпадающий список Link Binary With Libraries и нажимая на плюсик в нижней левой части этого списка добавим следующие библиотеки:
- AVFoundation.framework
- CoreMedia.framework
- CoreVideo.framework
- QuartzCore.framework
- libiconv.dylib
11. Импортируем заголовочный файл нашего SDK. Для этого откроем файл «QR Scanner-Prefix.pch» и добавим в него строчку:
#import "ZBarSDK.h"
12. Для нашего класса контроллера QR_ScannerViewController объявим поддержку протокола делегата <ZBarReaderDelegate>, для этого в файле QR_ScannerViewController.h поправим объявление класса:
@interface QR_ScannerViewController : UIViewController <ZBarReaderDelegate>{
UITextView *resultText;
UIImageView *resultImage;
}
13. Теперь мы полностью готовы к тому, чтобы заставить приложение начать делать что-то полезное. В файле QR_ScannerViewController.m изменим код scanButtonTapped на следующий:
- (IBAction)scanButtonTapped{
// Создаем объект, получающий картинку с камеры
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
/*
Мы будем считывать только QR-коды. Для этого мы сперва отключим распознавание всех поддерживаемых библиотекой штрих-кодов…
*/
[scanner setSymbology:0 config:ZBAR_CFG_ENABLE to:0];
/*
… а затем включим распознавание QR-кодов:
*/
[scanner setSymbology:ZBAR_QRCODE config:ZBAR_CFG_ENABLE to:1];
reader.readerView.zoom = 1.0;
/*
Далее показываем пользователю в модальном режиме представление (форму), сканирующую QR-код:
*/
[self presentModalViewController:reader animated:YES];
[reader release];
}
Теперь после нажатия на кнопку в приложении будет вызываться этот метод, который будет непосредственно вызывать представление, на котором будет отображаться картинка с камеры. Пользователю достаточно будет навести камеру на QR-код, после чего он будет считан и обработан.
14. Однако считать и обработать QR-код мало, надо еще показать пользователю результаты обработки. Для этого нам необходимо реализовать следующий метод делегата (все в том же QR_ScannerViewController.m):
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
/*
В результате распознавания в info в общем случае возвращается что-то «перечисляемое»:
*/
id<NSFastEnumeration> results = [info objectForKey:ZBarReaderControllerResults];
/*
Опять же в общем случае результатов может быть несколько, следующий код всего лишь берет первый считанный и распознанный QR-код:
*/
ZBarSymbol *symbol = nil;
for(symbol in results)
// Считываем первый полученный результат
break;
/*
Результат считывания и распознавания заносим в текстовое поле на форме через аутлет resultText:
*/
resultText.text = symbol.data;
/*
Исходную картинку с QR-кодом заносим в объект UIImageView через аутлет resultImage:
*/
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// Прячем форму, с помощью которой фотографировали QR-код
[picker dismissModalViewControllerAnimated:YES];
}
После работы этого метода с экрана будет убрано представление, фотографировавшее QR-код и показано исходное представление, разработанное нами в файле QR_ScannerViewController.xib. На этом представлении можно будет увидеть фото QR-кода и текст этого QR-кода.
15. Вот и все! Далее сохраняем проект, компилируем, запускаем на устройстве.
16. Для сканирования QR-кода необходимо нажать на кнопку «Сканировать QR-код» и навести камеру на изображение QR-кода. Программа автоматически «узнает» QR-код, сфотографирует его и распознает, после чего выведет содержащуюся в нем информацию на экран.
Описание процесса запуска приложений на устройстве мы оставили за кадром, т.к., во-первых, это достаточно долгий с точки зрения описания процесс, а, во-вторых, эта статья предполагает наличие у читателя некоторой информационной базы в части работы с Xcode, что неявно предполагает умение запускать разработанные приложения на физическом устройстве. Тем не менее, если у читателей возникнет желание, могу описать процесс организации запуска разработанных приложений на физическом устройстве в отдельной заметке.
Отмечу также, что использованная нами библиотека позволяет распознавать не только QR-коды, но и многие другие виды двухмерных кодов. Мы умышленно исключили из рассмотрения этот функционал, чтобы сконцентрироваться на задаче распознавания QR-кодов, а также чтобы стимулировать самостоятельное изучение данной библиотеки теми, кого она заинтересует.
В заключение несколько полезных ссылок по теме данной заметки:
1. Сайт разработчиков библиотеки ZBarSDK.
2. Википедия о QR-кодах