Read the Chinese character dot matrix data and display it through pictures

Keywords: OpenCV Ubuntu

1, Principle of Chinese character lattice font

1, Chinese character coding

1. Location code

The national standard code is a four digit hexadecimal number, and the location code is a four digit decimal number. Each national standard code or location code corresponds to a unique Chinese character or symbol. However, because we rarely use hexadecimal numbers, we often use location codes. The first two digits are called area codes, and the last two digits are called bit codes.
All national standard Chinese characters and symbols are distributed in a square matrix with 94 rows and 94 columns. Each row of the square matrix is called an "area", numbered from 01 to 94, and each column is called a "bit", numbered from 01 to 94. The four Arabic numerals formed by the combination of the area code and bit code of each Chinese character and symbol in the square matrix are their "location code"

2. Internal code

Chinese character internal code, also known as "Chinese character ASCII code", referred to as "internal code", refers to the code composed of 0 and 1 symbols used in the internal storage, processing and transmission of Chinese characters. After the input code is accepted, it is converted into the internal code by the "input code conversion module" of the Chinese character operating system, which is independent of the keyboard input method used. The internal code is the most basic code of Chinese characters. No matter what Chinese character system and Chinese character input method, the input Chinese character external code must be converted into internal code before it can be stored and processed.
Two bytes are required to represent a Chinese character with internal code, and the internal code of these two bytes is represented according to the following rules:

  • High byte = area code + 20h + 80h (or area code + A0H)
  • Low byte = bit code + 20h + 80h (or bit code + AOH)

2, Lattice font structure

In the dot matrix font of Chinese characters, each bit of each byte represents a point of a Chinese character. Each Chinese character is composed of a rectangular dot matrix, 0 represents no, 1 represents a point. Draw 0 and 1 in different colors to form a Chinese character.
The font is divided into horizontal matrix and vertical matrix according to the different points represented by bytes. In order to improve the display speed, the font matrix is made into vertical matrix, but at present, the storage mode of most font libraries is still horizontal matrix.
The commonly used dot matrix has three word libraries: 12121414.16 * 16

  • 16 * 16 dot matrix font

3, Chinese character dot matrix acquisition

1. Location code acquisition

Get calculation formula:
Lattice start position = ((area code - 1) * 94 + (bit code - 1)) * number of Chinese character lattice bytes

2. Chinese internal code acquisition

  • Relationship between Chinese character location code and internal code:
    High byte of internal code = area code + 20h + 80h (or area code + A0H)
    Low byte of internal code = bit code + 20h + 80h (or bit code + AOH)
  • Conversely, the location code is obtained according to the internal code
    Area code = high byte of internal code - A0H
    Bit code = low byte of internal code - AOH

2, Code writing

#include<iostream>
#include<opencv/cv.h>
#include"opencv2/opencv.hpp"
#include<opencv/cxcore.h>
#include<opencv/highgui.h>
#include<math.h>

using namespace cv;
using namespace std;

void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset);
void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset);
void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path);

int main(){
    String image_path="ekko.jpeg";//Name of picture
    char* logo_path="logo.txt";//Name of Chinese character file
    put_text_to_image(800,650,image_path,logo_path);
    return 0;
}

void paint_ascii(Mat& image,int x_offset,int y_offset,unsigned long offset){
    //Coordinates of the starting point of the drawing
	Point p;
	p.x = x_offset;
	p.y = y_offset;
	 //Storing ascii word film
	char buff[16];           
	//Open ascii font file
	FILE *ASCII;

	if ((ASCII = fopen("Asci0816.zf", "rb")) == NULL){
		printf("Can't open ascii.zf,Please check the path!");
		//getch();
		exit(0);
	}

	fseek(ASCII, offset, SEEK_SET);
	fread(buff, 16, 1, ASCII);

	int i, j;
	Point p1 = p;
	for (i = 0; i<16; i++)                  //Sixteen char s
	{
		p.x = x_offset;
		for (j = 0; j < 8; j++)              //One char and eight bit s
		{
			p1 = p;
			if (buff[i] & (0x80 >> j))    /*Test whether the current bit is 1*/
			{
				/*
					Because the original ascii word film was 8 * 16, it was not large enough,
					So the original pixel is replaced by four pixels,
					After replacement, there are 16 * 32 pixels
					ps: I think it's unnecessary to write code like this, but I only think of this method for the time being
				*/
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.x++;
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.y++;
				circle(image, p1, 0, Scalar(0, 0, 255), -1);
				p1.x--;
			   circle(image, p1, 0, Scalar(0, 0, 255), -1);
			}						
            p.x+=2;            //One pixel becomes four, so x and y should both be + 2
		}
		p.y+=2;
	}
}
void paint_chinese(Mat& image,int x_offset,int y_offset,unsigned long offset){//Draw Chinese characters on the picture
    Point p;
    p.x=x_offset;
    p.y=y_offset;
    FILE *HZK;
    char buff[72];//72 bytes for storing Chinese characters

    if((HZK=fopen("HZKf2424.hz","rb"))==NULL){
        printf("Can't open HZKf2424.hz,Please check the path!");
        exit(0);//sign out
    }
    fseek(HZK, offset, SEEK_SET);/*Move the file pointer to the offset position*/
    fread(buff, 72, 1, HZK);/*Read 72 bytes from the offset position, and each Chinese character occupies 72 bytes*/
    bool mat[24][24];//Define a new matrix to store the transposed text film
    int i,j,k;
    for (i = 0; i<24; i++)                 /*24x24 Dot matrix Chinese characters, a total of 24 lines*/
	{
        	for (j = 0; j<3; j++)                /*There are 3 bytes in the horizontal direction, and the value of each byte is determined by cycle*/
			for (k = 0; k<8; k++)              /*Each byte has 8 bits, and the loop judges whether each byte is 1*/
				if (buff[i * 3 + j] & (0x80 >> k))    /*Test whether the current bit is 1*/
				{
					mat[j * 8 + k][i] = true;          /*1 is stored in a new word film*/
				}
				else {
					mat[j * 8 + k][i] = false;
				}
	}
	
    for (i = 0; i < 24; i++)
	{
		p.x = x_offset;
		for (j = 0; j < 24; j++)
		{		
			if (mat[i][j])
				circle(image, p, 1, Scalar(255, 0, 0), -1);		  //Write (replace) pixels
			p.x++;                                                //Shift right one pixel
		}
		p.y++;                                                    //Move down one pixel
	}
}

void put_text_to_image(int x_offset,int y_offset,String image_path,char* logo_path){//Put Chinese characters on the picture
//x and y are the starting coordinates of the first word on the picture
    //Get pictures through picture path
    Mat image=imread(image_path);
    int length=22;//The length of characters to be printed (the length can be as many bytes as you print, which can be adjusted according to your own situation)
    unsigned char qh,wh;//Define area code and tag number
    unsigned long offset;//Offset
    unsigned char hexcode[30];//Hexadecimal used to store Notepad reading. Remember to use unsigned
    FILE* file_logo;

    if ((file_logo = fopen(logo_path, "rb")) == NULL){
		printf("Can't open txtfile,Please check the path!");
		//getch();
		exit(0);
	}

    fseek(file_logo, 0, SEEK_SET);
    fread(hexcode, length, 1, file_logo);
    int x =x_offset,y = y_offset;//x. Y: the starting coordinate of the text drawn on the picture

    for(int m=0;m<length;){
        if(hexcode[m]==0x23){
            break;//It ends when the # number is read
        }
        else if(hexcode[m]>0xaf){
            qh=hexcode[m]-0xaf;//The font used starts with Chinese characters, not Chinese symbols
            wh=hexcode[m+1] - 0xa0;//Calculation bit code
            offset=(94*(qh-1)+(wh-1))*72L;
            paint_chinese(image,x,y,offset);
            /*
            Calculate the offset in the Chinese character library
            Each Chinese character is represented by a 24 * 24 dot matrix
            A line has three bytes, a total of 24 lines, so 72 bytes are required
            */

            m=m+2;//The internal code of a Chinese character occupies two bytes,
            x+=24;//A Chinese character has 24 * 24 pixels. Because it is placed horizontally, it moves 24 pixels to the right
        }

        else{
        //When the read character is ASCII
        wh=hexcode[m];
        offset=wh*16l;//Calculate the offset of English characters
        paint_ascii(image,x,y,offset);
        m++;//English characters only occupy one byte in the file, so just move back one bit
        x+=16;
        }

    }

    cv::imshow("image", image);
    cv::waitKey();
}

After writing, you also need to download the Chinese dot matrix font library and display tool program.
After downloading, unzip the file shown in the figure to the directory, because the code will call this file

3, Experimental effect

1. After writing the code, create a file in the directory, then enter gedit word.cpp to edit the file, copy the code into the file and save it

2. After editing the file, input the command to compile:

g++ word.cpp -o word `pkg-config --cflags --libs opencv`

There are no errors

3. After compilation, enter the command:. / word to run the file
Operation effect:

4, Summary

After knowing the coding rules of Chinese character dot matrix, we can display any text we want on the picture.
There are some small details during the experiment:
1. In the program code, you need to modify the corresponding code according to the length of your displayed text
2. When inputting the text you want to display in the logo.txt file, it needs to be written in ANSI code, otherwise Chinese will be garbled
3. When selecting the position of text display, modify the code according to the pixel size of the selected picture file
For example, the pixel size of my picture file is 1215x717. I select the text to display in the lower right foot, and I modify it to put in my code_ text_ to_ image(800,650,image_path,logo_path);
reference material: Font reading and display of dot matrix Chinese characters.
Principle of Chinese character dot matrix font library (1).pdf.

Posted by fahad on Fri, 12 Nov 2021 00:35:43 -0800