qrencode生成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\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();
}

你可能感兴趣的:(linux,ImageMagick,zbar,qrencode)