INLET’s blog

浅学非才な工業大学生の悪あがき

モノクロ画像をAA化するC++プログラム

概要

大学の授業で使ったプログラムが画像ピクセルの値を読みだして色々するものだったので,01でテキストファイルに書き出せるよう改造しました.
VisualStudio2017で動くことを確認しています.

f:id:INLET:20181219134041j:plain
AA化のイメージ

使い方

二値化した画像をIrfanViewを用いて.pgm形式にします.
ソースファイルと同じ場所にcharacter.pgmを置いてプログラムを実行すると,同じ場所にcharacter.txtが作られます.
画像が存在しなかったり,二値化されていない画像を入れたりするとエラーを吐きます.

プログラム

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>


#define edmalloc(var,ty,n1,n2,msg) {\
if (NULL == ((var) = (ty**)malloc((sizeof(void *) * (n1))))) {	\
  fprintf(stderr,"%s: can't allocate memory.\n" ,msg); \
  exit(1); }					\
if (NULL == ((var)[0] = (ty*)malloc((n2 * n1)* (sizeof(ty))))) {\
  fprintf(stderr,"%s: can't allocate memory.\n" ,msg); \
  exit(1); }					       \
for (int _c1_=1; _c1_<(n1); _c1_++) { \
  (var)[_c1_] = (ty *)( ((char *)(var)[0]) + (_c1_ * sizeof(ty) * n2));	\
 }}

#define edfree(var) {	\
    free((var)[0]);free(var);}


int main(int argc, char **argv) {
	errno_t err;
	FILE *fp;
	char fname[256] = "character.pgm";
	err = fopen_s(&fp, fname, "r");
	if (err != 0) {
		fprintf(stderr, "%s was not opened\n", fname);
		return(-1);
	}

	char buf[1024];
	int ixsize, iysize;
	unsigned char **image;
	/* pgmのヘッダが4行であることを仮定 */
	fgets(buf, 1024, fp);
	fgets(buf, 1024, fp);
	fgets(buf, 1024, fp);
	sscanf_s(buf, "%d %d", &ixsize, &iysize);
	fgets(buf, 1024, fp);
	edmalloc(image, unsigned char, iysize, ixsize, "**image");
	fread(image[0], sizeof(unsigned char) * iysize * ixsize, 1, fp);
	fclose(fp);

	std::ofstream   File("character.txt");

	for (int y = 0; y < iysize; y++) {
		for (int x = 0; x < ixsize; x++) {
			if (image[y][x] == 0) {
				File << 1;
			}
			else if(image[y][x] == 255) {
				File << 0;
			}
			else {
				fprintf(stderr, "%s was not binarized\n", fname);
				return(-1);
			}
		}
		File << "\n";
	}

	edfree(image);
	
	return 1;
}