QRCodeを生成し、ImageMagickとzbarを使ってQRCodeから内容を読み取る。


#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
"); exit(-1); } } void readQRCodeImageInfo() { #define ThrowWandException(wand) \ { \ char \ *description; \ \ ExceptionType \ severity; \ \ description=MagickGetException(wand,&severity); \ (void) fprintf(stdout,"%s %s %lu %s
",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
", 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
", 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\"
", zbar_get_symbol_name(typ), data); } } else { printf("zbar_scan_image return %d, failed
", n); } free(pixel); magick_wand=DestroyMagickWand(magick_wand); MagickWandTerminus(); }