关于将汉字转换成BMP图片的问题(顺便散分)

时间:2022-01-20 17:49:57
好长时间没来了,顺便散分

我有几个问题想请教下,关于将数据文件里的内容转换成图片的问题。
1.想将文件中的内容转换成BMP图片,文件中的数据是由汉字,数字,字母和符号组成,这些内容是如何能转成像素内容的?是否有现成的工具?
2.bmp转jpg是有损压缩,这种有损压缩方法,会造成图片清晰度变差吗?

11 个解决方案

#1


该回复于2013-06-13 08:54:32被管理员删除

#2


1
显示字符串的原理很简单,按编码和字库直接找对应的像素矩阵
windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP

2
有损压缩方法会导致图片中的信息有损失,jpg格式采用的是保低频去高频的傅立叶变换,形象的说法的确可以说成是“图片内原本区分明显的地方变得有些模糊”
但有损无损压缩跟清晰不清晰没有必然联系,一切都要看具体情况

#3


Quote: 引用 2 楼 baichi4141 的回复:

1
显示字符串的原理很简单,按编码和字库直接找对应的像素矩阵
windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP

你说的这个编码是unicode吗?
“windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP”
这句不是太明白。

#4


1。屏幕copy,paste 到 画板。。。
2。你用肉眼看不出区别

#5


引用 4 楼 AnYidan 的回复:
1。屏幕copy,paste 到 画板。。。


我正在用程序写一个将文本数据转换成BMP图片的程序,所以想知道,文本中的数据是不是unicode方式存储的,或者是什么方式存储的,关于BMP格式有这样的描述
典型的BMP图像文件由四部分组成:
  1:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;
  2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
  3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
  4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。

    第4部分“位图数据”,想知道它是怎么生成的,是什么样的转换方法,将汉字转换成了位图数据。

#7


引用 6 楼 buyong 的回复:
http://blog.163.com/zhaoxin851055@126/blog/static/81129298201044101233113/




谢谢 6楼的朋友,这个是从屏幕上获取bmp像素图,然后保存,我想在的情况是将一组数据(汉字)生成一张BMP图片。

#8


自己顶一下,等大虾们回复。

#9


#pragma comment(lib,"gdi32")
#include <windows.h>
#include <stdio.h>

int main() {
    const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;

    PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);
    pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = uWidth;
    pbmi->bmiHeader.biHeight = uHeight;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;
    pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[0].rgbGreen = 0;
    pbmi->bmiColors[0].rgbRed = 0;
    pbmi->bmiColors[1].rgbBlue = 255;
    pbmi->bmiColors[1].rgbGreen = 255;
    pbmi->bmiColors[1].rgbRed = 255;

    HDC hDC = CreateCompatibleDC (0);
    void * pvBits;
    HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);
    SelectObject (hDC, hBitmap);
    HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
//  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");
    SelectObject (hDC, hFont);
    BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);

    char c[4];
    int i, j;
    for (i = 128; i < 256; i++) {
        sprintf (c, "%02X", i);
        TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);
    }
    for (j = 0; j < 256; j++) {
        sprintf (c, "%02X", j);
        TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);
    }
    for (i = 128; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            c[0] = (char) i;
            c[1] = (char) j;
            TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);
        }
    }
    for (i = 0; i < 130; i++) {
        MoveToEx (hDC, 0, i * 17, NULL);
        LineTo (hDC, uWidth, i * 17);
    }
    for (j = 0; j < 258; j++) {
        MoveToEx (hDC, j * 17, 0, NULL);
        LineTo (hDC, j * 17, uHeight);
    }

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = *(PWORD) "BM";
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;
    bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;

    HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE) {
        DWORD dwWritten;
        WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);
        WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);
        WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);

        CloseHandle (hFile);
    }

    DeleteObject (hFont);
    DeleteObject (hBitmap);
    DeleteDC (hDC);
    LocalFree (pbmi);

    return 0;
}

#10


该回复于2013-06-13 17:03:37被管理员删除

#11


我先 试试  谢谢 

#1


该回复于2013-06-13 08:54:32被管理员删除

#2


1
显示字符串的原理很简单,按编码和字库直接找对应的像素矩阵
windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP

2
有损压缩方法会导致图片中的信息有损失,jpg格式采用的是保低频去高频的傅立叶变换,形象的说法的确可以说成是“图片内原本区分明显的地方变得有些模糊”
但有损无损压缩跟清晰不清晰没有必然联系,一切都要看具体情况

#3


Quote: 引用 2 楼 baichi4141 的回复:

1
显示字符串的原理很简单,按编码和字库直接找对应的像素矩阵
windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP

你说的这个编码是unicode吗?
“windows下可以将字符串打印到内存设备环境中,再将内存设备环境中的设备相容图片取出保存为BMP”
这句不是太明白。

#4


1。屏幕copy,paste 到 画板。。。
2。你用肉眼看不出区别

#5


引用 4 楼 AnYidan 的回复:
1。屏幕copy,paste 到 画板。。。


我正在用程序写一个将文本数据转换成BMP图片的程序,所以想知道,文本中的数据是不是unicode方式存储的,或者是什么方式存储的,关于BMP格式有这样的描述
典型的BMP图像文件由四部分组成:
  1:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;
  2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;
  3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;
  4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。

    第4部分“位图数据”,想知道它是怎么生成的,是什么样的转换方法,将汉字转换成了位图数据。

#6


#7


引用 6 楼 buyong 的回复:
http://blog.163.com/zhaoxin851055@126/blog/static/81129298201044101233113/




谢谢 6楼的朋友,这个是从屏幕上获取bmp像素图,然后保存,我想在的情况是将一组数据(汉字)生成一张BMP图片。

#8


自己顶一下,等大虾们回复。

#9


#pragma comment(lib,"gdi32")
#include <windows.h>
#include <stdio.h>

int main() {
    const DWORD uWidth = 18 + 17 * 256, uHeight = 18 + 17 * 128;

    PBITMAPINFO pbmi = (PBITMAPINFO) LocalAlloc (LPTR, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2);
    pbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
    pbmi->bmiHeader.biWidth = uWidth;
    pbmi->bmiHeader.biHeight = uHeight;
    pbmi->bmiHeader.biPlanes = 1;
    pbmi->bmiHeader.biBitCount = 1;
    pbmi->bmiHeader.biSizeImage = ((uWidth + 31) & ~31) / 8 * uHeight;
    pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[0].rgbGreen = 0;
    pbmi->bmiColors[0].rgbRed = 0;
    pbmi->bmiColors[1].rgbBlue = 255;
    pbmi->bmiColors[1].rgbGreen = 255;
    pbmi->bmiColors[1].rgbRed = 255;

    HDC hDC = CreateCompatibleDC (0);
    void * pvBits;
    HBITMAP hBitmap = CreateDIBSection (hDC, pbmi, 0, &pvBits, NULL, 0);
    SelectObject (hDC, hBitmap);
    HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "宋体");
//  HFONT hFont = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, SHIFTJIS_CHARSET, 0, 0, 0, 0, "宋体");
    SelectObject (hDC, hFont);
    BitBlt (hDC, 0, 0, uWidth, uHeight, NULL, 0, 0, WHITENESS);

    char c[4];
    int i, j;
    for (i = 128; i < 256; i++) {
        sprintf (c, "%02X", i);
        TextOut (hDC, 1, (i - 127) * 17 + 1, c, 2);
    }
    for (j = 0; j < 256; j++) {
        sprintf (c, "%02X", j);
        TextOut (hDC, (j + 1)* 17 + 1, 1, c, 2);
    }
    for (i = 128; i < 256; i++) {
        for (j = 0; j < 256; j++) {
            c[0] = (char) i;
            c[1] = (char) j;
            TextOut (hDC, (j + 1) * 17 + 1, (i - 127) * 17 + 1, c, 2);
        }
    }
    for (i = 0; i < 130; i++) {
        MoveToEx (hDC, 0, i * 17, NULL);
        LineTo (hDC, uWidth, i * 17);
    }
    for (j = 0; j < 258; j++) {
        MoveToEx (hDC, j * 17, 0, NULL);
        LineTo (hDC, j * 17, uHeight);
    }

    BITMAPFILEHEADER bmfh;
    bmfh.bfType = *(PWORD) "BM";
    bmfh.bfReserved1 = 0;
    bmfh.bfReserved2 = 0;
    bmfh.bfOffBits = sizeof (BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2;
    bmfh.bfSize = bmfh.bfOffBits + pbmi->bmiHeader.biSizeImage;

    HANDLE hFile = CreateFile ("goal.bmp", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
    if (hFile != INVALID_HANDLE_VALUE) {
        DWORD dwWritten;
        WriteFile (hFile, &bmfh, sizeof (BITMAPFILEHEADER), &dwWritten, NULL);
        WriteFile (hFile, pbmi, sizeof (BITMAPINFOHEADER) + sizeof (RGBQUAD) * 2, &dwWritten, NULL);
        WriteFile (hFile, pvBits, pbmi->bmiHeader.biSizeImage, &dwWritten, NULL);

        CloseHandle (hFile);
    }

    DeleteObject (hFont);
    DeleteObject (hBitmap);
    DeleteDC (hDC);
    LocalFree (pbmi);

    return 0;
}

#10


该回复于2013-06-13 17:03:37被管理员删除

#11


我先 试试  谢谢