QR-код (аббревиатура QR расшифровывается как «Quick Response», «Быстрый отклик») представляет собой способ кодирования текстовой и графической информации в матричной форме. Если проводить аналогию со штрих-кодом, который является предшественником QR-кода, то первый - одномерный массив, а второй – двумерный. «Кем он придуман?», «зачем?» и тому подобные вопросы TC отправляет на обработку поисковику, а сам перейдет к концепту программы, которая распознает эти коды. QR-код прежде всего удобен тем, что поддается быстрому распознаванию. К примеру, если взять мобильник (или любой другой девайс, содержащий камеру любого разрешения) и сфотографировать картинку из прилагающегося к материалу архива (кстати, можно сделать банальный PrintScreen, но это выглядит менее эффектно) и пропустить через одну из программ распознавания QR-кодов, то в процессе всех этих манипуляций будет получена строка «http://forum.antichat.ru», которая, в свою очередь, была закодирована в эту картинку. Забавно. Однако авторы этих программ неохотно делятся секретами своих программных продуктов. Японцами написана библиотека, в которой реализовано распознавание QR-кодов, и прикреплен к ней весьма скудный мануал ее использования (она триальная, поэтому выдаваемая информация искажается). Приведу фрагмент кода (концепт), который использует библиотеку распознавания QR-кода: Code: using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.ComponentModel; using System.Data; using System.Drawing; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Program { /*Image file reading/writing APIs and definitions */ //DEFINES SECTION public const int PT_IMAGERW_FAIL = 0x00000000; //An error occurred in an operation. public const int PT_IMAGERW_SUCCESS = 0x00000001; //An operation is successful. public const int PT_IMAGERW_ALLOC_ERROR = 0x00000100; //Error while allocating memory. public const int PT_IMAGERW_FORMAT_UNSUPPORTED = 0x00000101; //The format of image is unsupported. //STRUCTURES SECTION unsafe public struct PTIMAGE { public int dwWidth; //The width of the image in pixels. public int dwHeight; //The height of the image in pixels. public byte* pBits; //Pointer to the image data. public byte* pPalette; //Pointer to the palette data (RGBQUAD)for 1,4,8 bits image. public short wBitsPerPixel; //Number of bits per pixel. } //FUNCTIONS SECTION [DllImport("PtImageRW.dll", EntryPoint = "PtInitImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern void PtInitImage(ref PTIMAGE pImage); [DllImport("PtImageRW.dll", EntryPoint = "PtLoadImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtLoadImage(string filename, ref PTIMAGE pImage, int FrameIndex); [DllImport("PtImageRW.dll", EntryPoint = "PtSaveImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtSaveImage(string filename, ref PTIMAGE pImage); [DllImport("PtImageRW.dll", EntryPoint = "PtShowImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern void PtShowImage(ref PTIMAGE pImage, IntPtr hDC, int x, int y, float scale); [DllImport("PtImageRW.dll", EntryPoint = "PtCreateImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtCreateImage(ref PTIMAGE pImage, int ImageSize, int PaletteSize); [DllImport("PtImageRW.dll", EntryPoint = "PtFreeImage", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern void PtFreeImage(ref PTIMAGE pImage); /*The PTDECODEPARA structure is used to decide parameter when decoding barcodes from an image.*/ public unsafe struct PTDECODEPARA { public int dwStartX; //The start X-coordinate in pixels of the search window in the image to decode the symbol. public int dwStartY; //The start Y-coordinate in pixels of the search window in the image to decode the symbol. public int dwEndX; //The end X-coordinate in pixels of the search window in the image to decode the symbol. public int dwEndY; //The end Y-coordinate in pixels of the search window in the image to decode the symbol. public int dwMaxCount; //The maximal number of symbols to be searched. If it's set to 0 then search the all symbols. } ; /*The PTBARCODEINFO structure contains a barcode information after decoding*/ public unsafe struct PTBARCODEINFO { public int dwX1, dwY1; //Four corners' coordinates in pixels of the barcode. public int dwX2, dwY2; public int dwX3, dwY3; public int dwX4, dwY4; public byte* pData; //Pointer to the buffer that contains the barcode's data. public int dwDataLen; //The barcode data's length in bytes. } ; /*The PTTOTALBARCODEINFO structure contains all barcodes' information after decoding*/ public unsafe struct PTTOTALBARCODEINFO { public PTBARCODEINFO* pInfoList; //Pointer to the start address of the list of barcodes' info. public int dwTotalCount; //The number of barcode that have been decoded. } ; /*QR Code symbol reading APIs and definitions*/ /* Status of an operation */ public const int PT_QRDECODE_FAIL = 0x00000000;//An error occurred in an operation. public const int PT_QRDECODE_SUCCESS = 0x00000001;//An operation is successful. public const int PT_QRDECODE_ALLOC_ERROR = 0x00000300;//Error while allocating the memory. public const int PT_QRDECODE_IMAGE_INVALID = 0x00000301;//The image to be decode is invalid. public const int PT_QRDECODE_PARAMETERS_INVALID = 0x00000302;//The parameters input to a function are invalid. //FUNCTIONS SECTION [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecodeRegister", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtQRDecodeRegister(string pKeyStr); [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecodeInit", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern void PtQRDecodeInit(ref PTTOTALBARCODEINFO pInfo); [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecode", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtQRDecode(ref PTIMAGE pImage, ref PTDECODEPARA pPara, ref PTTOTALBARCODEINFO pInfo); [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecodeFromFile", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtQRDecodeFromFile(string FileName, ref PTDECODEPARA pPara, ref PTTOTALBARCODEINFO pInfo); [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecodeFromBitmap", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern int PtQRDecodeFromBitmap(IntPtr hBitmap, ref PTDECODEPARA pPara, ref PTTOTALBARCODEINFO pInfo); [DllImport("PtQRDecode.dll", EntryPoint = "PtQRDecodeFree", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern void PtQRDecodeFree(ref PTTOTALBARCODEINFO pInfo); static private PTIMAGE image; static private PTTOTALBARCODEINFO BarCodeInfo; static private PTDECODEPARA DecodePara; static private string FileName; [STAThreadAttribute] static void Main(string[] args) { PtQRDecodeRegister("12345678901234567890");//use the license key of demo version. PtInitImage(ref image); System.Windows.Forms.OpenFileDialog OpenFileDlg=new System.Windows.Forms.OpenFileDialog(); OpenFileDlg.Filter = "Image File|*.bmp;*.jpg;*.tif;*.tiff;*.gif;*.png"; if (OpenFileDlg.ShowDialog() == DialogResult.OK) { if (OpenFileDlg.FileName != "") { FileName = OpenFileDlg.FileName; DecodeQR(); } else MessageBox.Show("Неправельный файл"); } else { MessageBox.Show("Требуется нажатие кнопки ОК"); } } static private void DecodeQR() { DecodePara.dwStartX = 0; DecodePara.dwStartY = 0; DecodePara.dwEndX = 0; DecodePara.dwEndY = 0;//search the whole image. DecodePara.dwMaxCount = 0;//search the all symbols in the image. PtQRDecodeInit(ref BarCodeInfo); if (PtLoadImage(FileName, ref image, 0) == PT_IMAGERW_SUCCESS) { if (PtQRDecode(ref image, ref DecodePara, ref BarCodeInfo) != PT_QRDECODE_SUCCESS) MessageBox.Show("An error occured while rocognition "); else ShowBarCodeInfo(ref BarCodeInfo); } PtFreeImage(ref image); PtQRDecodeFree(ref BarCodeInfo); } static public unsafe void ShowBarCodeInfo(ref PTTOTALBARCODEINFO BarCodeInfo) { if (BarCodeInfo.dwTotalCount <= 0) { MessageBox.Show("No barcode was found"); return; } string str = ""; PTBARCODEINFO* pInfoList = BarCodeInfo.pInfoList; for (int count = 0; count < BarCodeInfo.dwTotalCount; count++) { str = str + "barcode " + Convert.ToString(count + 1) + ":\n"; byte[] byteArray = new byte[pInfoList->dwDataLen]; for (int i = 0; i < pInfoList->dwDataLen; i++) byteArray[i] = pInfoList->pData[i]; str = str + Encoding.Default.GetString(byteArray);//Encoding.GetEncoding("GB2312").GetString str = str + "\n\n"; pInfoList++; } str = str + '\0'; MessageBox.Show(str); } } } Думаю, что интересующимся альтернативным кодированием информации, этот код будет весьма «кстати». Что делать с ним дальше – дело читателя, и свобода действий ограничена лишь количеством извилин в его голове. В качестве бонуса, выложен проект для Visual Studio 2008, который демонстрирует прелесть QR-кодов, а именно: всеядность программного обеспечения, распознающего эти коды. http://depositfiles.com/files/m217feydd (пароль: antichat.ru) (c) c0n Difesa (defec.ru)
Не думаю, что информацию удастся скрыть от человека, вооруженного камерой и знанием понятия QR-кода (и его наличием в передаваемом сообщении). QR-код не может использоваться как метод стеганографии напрямую, однако ему можно найти косвенные применения.
Я не разбираюсь в этих кодах. Поэтому такой вопрос, что лучше QR код или штих-код? И если QR почему все используют штрих код? И действительно в каких ситуациях они могут понадобится программисту?
Ответ: QR-код, т.к. он позволяет хранить гораздо больше информации из-за особенности своей структуры (матричная форма хранения информации), и типом информации может выступать как текст (не многим более 4000 символов, что несомненно превышает объем хранимой информации в штрих-коде), так и картинка. Не все. В Японии, например, вследствие нехватки объема хранимой информации в штрих-коде, происходит достаточно быстрый переход на новый стандарт QR. Однако, Россия не спешит менять программное обеспечение, да и не за чем, ведь пока хватает «старичка» штрих-кода. С трудом понял вопрос, но попытаюсь перебрать несколько вариантов ответа. Программисту может понадобиться только SDK работы с ним… А вот что касается практического применения (относится не только к программистам), то тут уйма ситуаций: - если закодировать адрес электронной почты, ICQ, номер телефона и т.п. информацию в аватарке на сайте, то большинство спам-ботов идут «косить изюм»… - из предыдущего пункта пока актуальна защита от спам-ботов при регистрации на сайтах - объявления, реклама, приглашения, визитка и много другое можно закодировать в QR-код.
Посмотрел програмку распознавания. Из плюсов: 1) Распознавание инвариантно положению картинки (хорошо распознает QR внутри произвольной картинки) 2) Инвариантно масштабированию QR кода 3) Инвариантно поворотам Из минусов: НЕ инвариантно любым преобразованиям с изменением соотнешения сторон QR кода. В результате: Хоршо распознаются на плоскости. Но в 3D, к сожалению - нет...
Триал у них одно название, если кому надо то вот дллки, что использовались, без триала) http://www.sendspace.com/file/uvw7ii кстати PtQRDecodeRegister, вызывать ненужно.
В силу своей специфики высокой степени распознаваемости, QR-коду можно найти 1000 и одно применение. Проходивший в этом году конкурс студентов-разработчиков «Imagine Cup» был посвящен теме глобальных проблем современного мира. Занявшая второе место на российском этапе (поясню: сначала команда проходит отбор среди других ВУЗовских команд своего региона, затем уже открывается доступ на этап России, после которого команда-победитель едет на этап мира в Каир) команда одного московского ВУЗа использовала в своем проекте как раз концепцию, основанную на QR-кодах. Идея состояла в следующем: расширить видимую реальность с помощью подручных средств, коими являются мобильные телефоны с камерой любого разрешения. Почему именно мобильники, не вижу смысла объяснять. Специально написанный фреймворк устанавливался на мобильный телефон. Далее обладатель телефона (предполагался индивид с ограниченными слуховыми способностями, что, в принципе не имеет особого значения), который интересовался, например, меню какого-либо ресторана (бара, кафе, закусочной и др. зданием, содержащим QR-код, который несет полезную информацию), при наведении камерой на здание мог спокойно увидеть в реальном времени на дисплее своего телефона меню или любую другую информацию, которую несет код. Код, размещенный на здании, так же мог отправить в фоновом режиме браузер телефона по ссылке на специальный сайт за детальной информацией.
проект который в первом посте http://depositfiles.com/files/m217feydd (пароль: antichat.ru) с оригинальными DLL-ками работает нормально. если DLL - ки заменить то начинает ругаться.