Operación simple de mapa de bits

Implemente varios temas comunes en el diseño de cursos de lenguaje C de la manera más sencilla, adecuada para estudiantes de primer año o estudiantes que recién están aprendiendo lenguaje C. Los proyectos de C puro creados con el compilador Code::Blocks también se pueden ejecutar directamente pegando el código fuente en otros compiladores o proyectos de C++. Debido a que algunos estudiantes no han estudiado las estructuras de datos, intentan usar matrices tradicionales para el almacenamiento para evitar puntos de conocimiento que no han aprendido, pero alientan a todos a mejorar por sí mismos. Para hacer que el programa sea más simple y fácil de leer, básicamente no hay tolerancia a fallas para la entrada del usuario, y puede agregarla usted mismo.

Código::Bloquea la instalación y el usohttps://blog.csdn.net/qq_42283621/article/details/124055391?spm=1001.2014.3001.5501

El código fuente del proyecto se proporcionará al final del artículo, porque hay dos mapas de bits que todos pueden usar, por lo que el proyecto se coloca en github sincrónicamente https://github.com/Last-Malloc/ mezcla

análisis de la demanda

La función es muy simple. Mezcla los píxeles de dos imágenes de mapa de bits en una imagen de mapa de bits, que se implementa mediante instrucciones. El formato de instrucción es

mezclar src1.bmp 80% src2.bmp dst.bmp

blend: el nombre del programa ejecutable,
src1.bmp src2.bmp: el nombre del archivo de imagen original,
80%: el porcentaje de mezcla, es decir, el 80% de los píxeles de src1.mbp y el 20% de los píxeles de
src2. bmp dst.bmp: el nuevo generado El nombre de archivo del archivo
se puede modificar a excepción de blend.

Primero mira el efecto

imagen-20220419162413152

imagen-20220419162419986

imagen-20220419162428402

Explicación básica

archivo ejecutable exe

Usamos code::blocks para crear un proyecto llamado blend en C. Después de hacer clic en Build and Run, puede ver que hay un blend.exe en el directorio blend/bin/Debug, que es un programa ejecutable con el mismo nombre que el proyecto.

imagen-20220419220238050

imagen-20220419220050474

En esta pantalla, mantenga presionada la tecla Mayús y haga clic con el botón derecho y seleccione "Ejecutar ventana de PowerShell aquí".

imagen-20220419220153620

Ingrese ./blend.exe para ejecutar este programa, es decir, además de hacer clic en el botón ejecutar en el compilador para ejecutar el programa, también puede usar la línea de comando para ejecutar el programa.

imagen-20220419220335937

Es muy importante tener en cuenta que si usa el botón ejecutar (triángulo verde) en Code::Blocks, el directorio raíz es donde se encuentra main.cpp, pero si usa la línea de comando anterior para ejecutar, entonces el directorio raíz es blend.exe donde, es decir, debe poner las dos imágenes originales al lado de blend.exe, luego las nuevas imágenes generadas también aparecerán al lado de blend.exe

imagen-20220420102345696

función principal con parámetros

La función principal de main.c que vimos arriba es int main(), que es nuestro tipo más común. De hecho, la función principal puede tomar parámetros, es decir, int main(int argc, char* argv[]), argc es el número de parámetros y argv es argc parámetros. Podemos generar estos parámetros argc.

Como puede ver, genera un parámetro, que es la ruta completa de blend.exe. Haces clic en compilar para ejecutar el código desde un compilador como Code::blocks Por defecto, hay un parámetro que es la ruta al archivo ejecutable.

imagen-20220419220816756

De la misma manera que antes, abra una ventana de Powershell, luego

Ingrese .\blend.exe, genere la ruta completa de blend.exe, es decir, solo hay un parámetro predeterminado.La ruta completa de blend.exe
Ingrese .\blend.exe aaa bbb ccc ddd, genere 5 parámetros, además a los parámetros predeterminados, también hay 4 parámetros que ingresamos, a saber, aaa bbb ccc ddd

imagen-20220419221127796

archivo de mapa de bits

https://blog.csdn.net/swordjun/article/details/108667926
https://blog.csdn.net/weixin_41336592/article/details/109710440

Composición de archivos BMP

Hay 4 partes:
Encabezado de archivo de mapa de bits (encabezado de archivo de mapa de bits) Encabezado de información de
mapa de bits de 14 bytes (encabezado de información de mapa de bits) Tabla de colores de 40 bytes
(tabla de colores) La imagen en color verdadero de 24 bits no tiene datos de mapa de bits de este
color (datos de bits)

Este artículo solo explica el uso de imágenes en color verdadero de 24 bits

Encabezado del archivo de mapa de bits:
imagen-20220420091032019

Encabezado de información de mapa de bits:
imagen-20220420091101707

Se pueden definir dos estructuras para leer el encabezado del archivo y el encabezado de información. Para una imagen en color verdadero de 24 bits, los primeros 54 bits (0-53) son la información del archivo (como se muestra en las dos figuras anteriores), a partir del byte 54 (el subíndice comienza en 0), que es la red de color datos. El formato de los datos de la red de colores es BGR, las filas son de izquierda a derecha y las columnas son de abajo hacia arriba. Esto puede ser vago. Echemos un vistazo al siguiente ejemplo. Por ejemplo, para una imagen en color verdadero de 4 x 4 píxeles, la cantidad de píxeles debe ser 4 x 4 x 3 = 48 bits. La Figura 1 es el formato de imagen que pensamos intuitivamente y la Figura 2 es el formato que realmente almacena en el archivo. .
imagen-20220420100039828

//位图文件头
struct bfHead
{
    
    
    char bfType[2]; //检查读入的文件是否是"BM"类型
	long bfSize;
	long bfReserved;
	long bfOffBits;
};

//位图信息头
struct biHead
{
    
    
	long biSize;
	long biWidth;   //图的宽度
	long biHeight;  //图的高度
	short biPlanes;
	short biBitCount;   //像素点位深度,24则为24位真彩图
	long biCompression;
	long biSizeImage;
	long biXPelsPerMeter;
	long biYpelsPerMeter;
	long biClrUsed;
	long biClrImportant;
};

Los campos útiles en el encabezado del archivo de mapa de bits y el encabezado de información de mapa de bits que se usan más adelante son los campos que se anotan en el código anterior.

Realización de funciones

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//存放图片的颜色点阵数据RGB
char src1[1000][1000][3];
char src2[1000][1000][3];
char dst[1000][1000][3];

//位图文件头
struct bfHead
{
    
    
    char bfType[2]; //检查读入的文件是否是"BM"类型
	long bfSize;
	long bfReserved;
	long bfOffBits;
};

//位图信息头
struct biHead
{
    
    
	long biSize;
	long biWidth;   //图的宽度
	long biHeight;  //图的高度
	short biPlanes;
	short biBitCount;   //像素点位深度,24则为24位真彩图
	long biCompression;
	long biSizeImage;
	long biXPelsPerMeter;
	long biYpelsPerMeter;
	long biClrUsed;
	long biClrImportant;
};

int main(int argc, char* argv[])
{
    
    
    struct bfHead bfSrc1, bfSrc2;
    struct biHead biSrc1, biSrc2;

    //打开2个原始文件 供读取数据
    FILE *fp1 = fopen(argv[1], "r+b");
    FILE *fp2 = fopen(argv[3], "r+b");

    //混合的百分比,例如输入 80% 则percent为0.8
    double percent = 0;
    for (int i = 0; i < strlen(argv[2]) - 1; ++i)
        percent = percent * 10 + (argv[2][i] - '0');
    percent /= 100;

    //打开目标文件 供写入数据
    //这个文件可能是没有的,fopen会创建一个新的文件;如果该文件已经存在,fopen会将其覆盖掉
    FILE *fp3 = fopen(argv[4], "w+b");

    //读取位图文件头 位图信息头
    fread(&bfSrc1, 14, 1, fp1);
    fread(&bfSrc2, 14, 1, fp2);
    fread(&biSrc1, 40, 1, fp1);
    fread(&biSrc2, 40, 1, fp2);

    //检查是否为BM类型 是否为24位真彩图 照片尺寸是否相等
    if (bfSrc1.bfType[0]=='B'&& bfSrc1.bfType[1]=='M' && bfSrc2.bfType[0]=='B' && bfSrc2.bfType[1]=='M'
        && biSrc1.biBitCount == 24 && biSrc2.biBitCount == 24
        && biSrc1.biWidth == biSrc2.biWidth && biSrc1.biHeight == biSrc2.biHeight)
    {
    
    
        //读取颜色点阵数据
        //遍历列 从下向上
        for (int y = biSrc1.biHeight - 1; y >= 0; --y)
        {
    
    
            //遍历行 从前向后
            for (int x = 0; x < biSrc1.biWidth; ++x)
            {
    
    
                //文件数据流中按照BGR的顺序存储,我们以RGB的顺序存储
                for (int k = 2; k >= 0; --k)
                {
    
    
                    fread(&src1[x][y][k], 1, 1, fp1);
                    fread(&src2[x][y][k], 1, 1, fp2);
                }
            }
        }

        //混合像素到目标文件数据
        for (int y = biSrc1.biHeight - 1; y >= 0; --y)
        {
    
    
            for (int x = 0; x<biSrc1.biWidth; ++x)
            {
    
    
                for (int k = 2; k >= 0; --k)
                    dst[x][y][k] = src1[x][y][k] * percent + src2[x][y][k] * (1 - percent);
            }
        }

        //写目标文件
        fwrite(&bfSrc1,14,1,fp3);
        fwrite(&biSrc1,40,1,fp3);
        for (int y = biSrc1.biHeight - 1; y >= 0; --y)
        {
    
    
            for (int x = 0; x<biSrc1.biWidth; ++x)
            {
    
    
                for (int k = 2; k >= 0; --k)
                    fwrite(&dst[x][y][k], 1, 1, fp3);
            }
        }

        printf("执行成功\n");
    }

    //关闭文件
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);

    return 0;
}

Efecto global

Después de guardar, haga clic en compilar y ejecutar, y descubra que el valor de retorno es incorrecto, esto es normal, no importa

imagen-20220420102639377

En el directorio blend/bin/Debug, mantenga presionada la tecla Mayús y haga clic con el botón derecho, seleccione "Ejecutar ventana de PowerShell aquí" e ingrese lo siguiente:

imagen-20220420102918653

Antes de señalar y después de la ejecución, los archivos debajo de la carpeta son los siguientes:

imagen-20220420102821564

imagen-20220420102828269

Supongo que te gusta

Origin blog.csdn.net/qq_42283621/article/details/124291665
Recomendado
Clasificación