#include <iostream> #include <qrencode.h> #include <cstdio> #include <cstring> #include <cstdlib> #include <wand/MagickWand.h> #include <zbar.h> using namespace std; using namespace zbar; //#define QRCODE_TEXT "http://www.ultramundum.org/index.htm"; // Text to encode into QRCode #define QRCODE_TEXT "这是一个测试。Hello, QR Code!"; // Text to encode into QRCode #define OUT_FILE "./test.bmp" // Output file name #define OUT_FILE_PIXEL_PRESCALER 8 // Prescaler (number of pixels in bmp file for each QRCode pixel, on each dimension) #define PIXEL_COLOR_R 0 // Color of bmp pixels #define PIXEL_COLOR_G 0 #define PIXEL_COLOR_B 0xff typedef unsigned short WORD; typedef unsigned int DWORD; typedef signed int LONG; #define BI_RGB 0L //!!!imported for create bmp image!!! #pragma pack(2) typedef struct { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER; typedef struct { DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; #pragma pack() void CreateQRCodeImage(); void readQRCodeImageInfo(); int main() { CreateQRCodeImage(); readQRCodeImageInfo(); return 0; } void CreateQRCodeImage() { const char* szSourceSring = QRCODE_TEXT; unsigned int unWidth, x, y, l, n, unWidthAdjusted, unDataBytes; unsigned char* pRGBData, *pSourceData, *pDestData; QRcode* pQRC; FILE* f; if ((pQRC = QRcode_encodeString(szSourceSring, 0, QR_ECLEVEL_H, QR_MODE_8, 1)) != NULL) { unWidth = pQRC->width; unWidthAdjusted = unWidth * OUT_FILE_PIXEL_PRESCALER * 3; if (unWidthAdjusted % 4) unWidthAdjusted = (unWidthAdjusted / 4 + 1) * 4; unDataBytes = unWidthAdjusted * unWidth * OUT_FILE_PIXEL_PRESCALER; // Allocate pixels buffer if (!(pRGBData = (unsigned char*)malloc(unDataBytes))) { printf("Out of memory"); exit(-1); } // Preset to white memset(pRGBData, 0xff, unDataBytes); // Prepare bmp headers BITMAPFILEHEADER kFileHeader = {0}; kFileHeader.bfType = 0x4d42; // "BM" kFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + unDataBytes; kFileHeader.bfReserved1 = 0; kFileHeader.bfReserved2 = 0; kFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); BITMAPINFOHEADER kInfoHeader; kInfoHeader.biSize = sizeof(BITMAPINFOHEADER); kInfoHeader.biWidth = unWidth * OUT_FILE_PIXEL_PRESCALER; kInfoHeader.biHeight = -((int)unWidth * OUT_FILE_PIXEL_PRESCALER); kInfoHeader.biPlanes = 1; kInfoHeader.biBitCount = 24; kInfoHeader.biCompression = BI_RGB; kInfoHeader.biSizeImage = 0; kInfoHeader.biXPelsPerMeter = 0; kInfoHeader.biYPelsPerMeter = 0; kInfoHeader.biClrUsed = 0; kInfoHeader.biClrImportant = 0; // Convert QrCode bits to bmp pixels pSourceData = pQRC->data; for(y = 0; y < unWidth; y++) { pDestData = pRGBData + unWidthAdjusted * y * OUT_FILE_PIXEL_PRESCALER; for(x = 0; x < unWidth; x++) { if (*pSourceData & 1) { for(l = 0; l < OUT_FILE_PIXEL_PRESCALER; l++) { for(n = 0; n < OUT_FILE_PIXEL_PRESCALER; n++) { *(pDestData + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_B; *(pDestData + 1 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_G; *(pDestData + 2 + n * 3 + unWidthAdjusted * l) = PIXEL_COLOR_R; } } } pDestData += 3 * OUT_FILE_PIXEL_PRESCALER; pSourceData++; } } // Output the bmp file if ((f = fopen(OUT_FILE, "wb")) != NULL) { fwrite(&kFileHeader, sizeof(BITMAPFILEHEADER), 1, f); fwrite(&kInfoHeader, sizeof(BITMAPINFOHEADER), 1, f); fwrite(pRGBData, sizeof(unsigned char), unDataBytes, f); fclose(f); } else { printf("Unable to open file"); exit(-1); } // Free data free(pRGBData); QRcode_free(pQRC); } else { printf("QRcode_encodeString failed\n"); exit(-1); } } void readQRCodeImageInfo() { #define ThrowWandException(wand) \ { \ char \ *description; \ \ ExceptionType \ severity; \ \ description=MagickGetException(wand,&severity); \ (void) fprintf(stdout,"%s %s %lu %s\n",GetMagickModule(),description); \ description=(char *) MagickRelinquishMemory(description); \ exit(-1); \ } MagickBooleanType status; MagickWand *magick_wand; MagickWandGenesis(); magick_wand=NewMagickWand(); status=MagickReadImage(magick_wand,"./test.bmp"); if (status == MagickFalse) ThrowWandException(magick_wand); size_t width, height; width = MagickGetImageWidth(magick_wand); height = MagickGetImageHeight(magick_wand); if (status == MagickFalse) { ThrowWandException(magick_wand); } else { printf("width=%d, height=%d\n", width, height); } void *pixel = malloc(width*height); //get gray pixel status = MagickExportImagePixels(magick_wand, 0, 0, width, height, "I", CharPixel, pixel); if (status == MagickFalse) ThrowWandException(magick_wand); zbar_image_scanner_t *scanner = zbar_image_scanner_create(); /* configure the reader */ zbar_image_scanner_set_config(scanner, ZBAR_NONE, ZBAR_CFG_ENABLE, 1); /* size_t blobSize; unsigned char *blob = MagickGetImagesBlob(magick_wand, &blobSize); printf("blob size = %d\n", blobSize); */ /* wrap image data */ zbar_image_t *image = zbar_image_create(); zbar_image_set_format(image, *(int*)"Y800"); zbar_image_set_size(image, width, height); zbar_image_set_data(image, pixel, width*height, zbar_image_free_data); /* scan the image for barcodes */ int n = zbar_scan_image(scanner, image); //n == 0 is failed if (n > 0) { /* extract results */ const zbar_symbol_t *symbol = zbar_image_first_symbol(image); for(; symbol; symbol = zbar_symbol_next(symbol)) { /* do something useful with results */ zbar_symbol_type_t typ = zbar_symbol_get_type(symbol); const char *data = zbar_symbol_get_data(symbol); printf("decoded %s symbol \"%s\"\n", zbar_get_symbol_name(typ), data); } } else { printf("zbar_scan_image return %d, failed\n", n); } free(pixel); magick_wand=DestroyMagickWand(magick_wand); MagickWandTerminus(); }