测试通过的C代码:平台无关的RGB保存为BMP格式的图片

简介: 测试通过的C代码:平台无关的RGB保存为BMP格式的图片

根据工作要求,得到视频数据。那么怎么证明视频数据是对的?转为BMP最简单了。这样一个想法,折腾了吾很久,找到了快10种代码,结果都不能用。后来终于找到了一个可用的(代码是部分的),看到保存出来的BMP图片,终于松了一口气。


 想直接用的朋友,去这里:https://github.com/quantum6/RgbToBmp



 个人发现关键地方有:


文件头。

文件头的对齐。

每行数据的对齐。

 取之于网络,用之于网络,吾将代码公布出来:


1、这里处理的是ARGB,如果是RGB,注意差异。


2、宽度最好是32的倍数。如果不是,注意bytesPerLine对数据区的越界影响。


主代码

看着这么整齐的代码,是不是赏心悦目?这么好的做法,阁下应该学习使用。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char   BYTE;
typedef unsigned short  WORD;
typedef unsigned int    DWORD;
typedef int    LONG;
#define BITS_PER_PIXCEL 24
#define FORMAT_RGBA 4
#define FORMAT_RGB  3
/** must needed. pack */
#pragma pack(1)
typedef struct
{
    WORD    bfType;
    DWORD   bfSize;
    WORD    bfReserved1;
    WORD    bfReserved2;
    DWORD   bfOffBits;
} BMP_FILE_HEADER;
typedef struct{
    DWORD      biSize;
    LONG       biWidth;
    LONG       biHeight;
    WORD       biPlanes;
    WORD       biBitCount;
    DWORD      biCompression;
    DWORD      biSizeImage;
    LONG       biXPelsPerMeter;
    LONG       biYPelsPerMeter;
    DWORD      biClrUsed;
    DWORD      biClrImportant;
} BMP_INFO_HEADER;
#pragma pack()
int rgbaToBmpFile(const char *pFileName, const char* pRgbaData, const int nWidth, const int nHeight, const int format)
{
    BMP_FILE_HEADER bmpHeader;
    BMP_INFO_HEADER bmpInfo;
    FILE* fp         = NULL;
    char* pBmpSource = NULL;
    char* pBmpData   = NULL;
    int i = 0, j=0;
    //4 bytes pack. must be 4 times per line。
    int bytesPerLine = (nWidth*BITS_PER_PIXCEL+31)/32*4;
    int pixcelBytes  = bytesPerLine*nHeight;
    bmpHeader.bfType        = 0x4D42;
    bmpHeader.bfReserved1   = 0;
    bmpHeader.bfReserved2   = 0;
    bmpHeader.bfOffBits     = sizeof(BMP_FILE_HEADER) + sizeof(BMP_INFO_HEADER);
    bmpHeader.bfSize        = bmpHeader.bfOffBits     + pixcelBytes;
    bmpInfo.biSize          = sizeof(BMP_INFO_HEADER);
    bmpInfo.biWidth         = nWidth;
    /** 这样图片才不会倒置 */
    bmpInfo.biHeight        = -nHeight; 
    bmpInfo.biPlanes        = 1;
    bmpInfo.biBitCount      = BITS_PER_PIXCEL;
    bmpInfo.biCompression   = 0;
    bmpInfo.biSizeImage     = pixcelBytes;
    bmpInfo.biXPelsPerMeter = 100;
    bmpInfo.biYPelsPerMeter = 100;
    bmpInfo.biClrUsed       = 0;
    bmpInfo.biClrImportant  = 0;
    /** convert in memort, then write to file. */
    pBmpSource = (char*)malloc(pixcelBytes);
    if (!pBmpSource)
    {
        return -1;
    }
    /** open file */
    fp = fopen(pFileName,"wb+");
    if (!fp)
    {
        return -1;
    }
    fwrite(&bmpHeader, sizeof(BMP_FILE_HEADER), 1, fp);
    fwrite(&bmpInfo,   sizeof(BMP_INFO_HEADER), 1, fp);
    /** Here you should consider color format. RGBA ? RGB? BGR?
        Param format is RGBA, format for file is BGR */
    pBmpData = pBmpSource;
    for (i=0; i<nHeight; i++)
    {
        for (j=0; j<nWidth; j++)
        {
           pBmpData[0] = pRgbaData[2];
           pBmpData[1] = pRgbaData[1];
           pBmpData[2] = pRgbaData[0];
           pRgbaData  += format;
           pBmpData   += FORMAT_RGB;
        }
        //pack for 4 bytes
        pBmpData +=(bytesPerLine - nWidth*FORMAT_RGB);
    }
    fwrite(pBmpSource, pixcelBytes, 1, fp);
    /** close and release。 */
    fclose(fp);
    free(pBmpSource);
    return 0;
}

剪裁

int clipRgbaToBmpFile(const char *pFileName, const char* pRgbaData,
    const int nWidth, const int nHeight, const int format,
    const int nClipLeft, const int nClipTop, const int nClipWidth, const int nClipHeight)
{
    char* pClipSource     = NULL;
    char* pClipData       = NULL;
    int pixcelBytes       = nClipWidth*nClipHeight*format;
    int i = 0;
    pClipSource = (char*)malloc(pixcelBytes);
    if (!pClipSource)
    {
        return -1;
    }
    //move to right position
    pRgbaData += nClipTop  * nWidth * format;
    pRgbaData += nClipLeft          * format;
    pClipData = pClipSource;
    for (i=0; i<nClipHeight; i++)
    {
        memcpy(pClipData, pRgbaData, nClipWidth*format);
        pRgbaData += nWidth    * format;
        pClipData += nClipWidth* format;
    }
    rgbaToBmpFile(pFileName, pClipSource, nClipWidth, nClipHeight, format);
    //release
    free(pClipSource);
    return 0;
}


调用范例

 此文貌似是网上第一个正确产生BMP的代码。很多人搜索到了之后,说是不知道怎么用。本来吾以为这是很简单的事情。从评论中看到有的朋友对编程都不是太了解,于是,吾决定加个调用范例。


 以下代码通过测试,可以产生红色BMP图片。各位修改宽高颜色等。


int main(const int argc, const char** argv)
{
    int  width  = 640;
    int  height = 360;
    int  format = FORMAT_RGB;
    char colorR = 0xFF;
    char colorG = 0x00;
    char colorB = 0x00;
    int size=width*height*format;
    char* pRgb=(char*)malloc(size);
    for (int i=0; i<width*height; i++)
    {
        pRgb[i*format]   = colorR;
        pRgb[i*format+1] = colorG;
        pRgb[i*format+2] = colorB;
    }
    rgbaToBmpFile((char*)"test.bmp", pRgb, width, height, format);
    free(pRgb);
}


编译

gcc \
    rgb2bmp.cpp \
    -o rgb2bmp

祝愿大家身体健康,工作顺利。

目录
相关文章
|
2月前
|
数据采集 机器学习/深度学习 大数据
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
这篇文章详细介绍了C3D架构在行为检测领域的应用,包括训练和测试步骤,使用UCF101数据集进行演示。
81 1
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
|
2月前
|
机器学习/深度学习 人工智能 监控
提升软件质量的关键路径:高效测试策略与实践在软件开发的宇宙中,每一行代码都如同星辰般璀璨,而将这些星辰编织成星系的过程,则依赖于严谨而高效的测试策略。本文将引领读者探索软件测试的奥秘,揭示如何通过精心设计的测试方案,不仅提升软件的性能与稳定性,还能加速产品上市的步伐,最终实现质量与效率的双重飞跃。
在软件工程的浩瀚星海中,测试不仅是发现缺陷的放大镜,更是保障软件质量的坚固防线。本文旨在探讨一种高效且创新的软件测试策略框架,它融合了传统方法的精髓与现代技术的突破,旨在为软件开发团队提供一套系统化、可执行性强的测试指引。我们将从测试规划的起点出发,沿着测试设计、执行、反馈再到持续优化的轨迹,逐步展开论述。每一步都强调实用性与前瞻性相结合,确保测试活动能够紧跟软件开发的步伐,及时适应变化,有效应对各种挑战。
|
1天前
|
算法 Java 测试技术
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
使用 BenchmarkDotNet 对 .NET 代码进行性能基准测试
29 13
|
28天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
62 1
|
1月前
|
人工智能 供应链 安全
AI辅助安全测试案例某电商-供应链平台平台安全漏洞
【11月更文挑战第13天】该案例介绍了一家电商供应链平台如何利用AI技术进行全面的安全测试,包括网络、应用和数据安全层面,发现了多个潜在漏洞,并采取了有效的修复措施,提升了平台的整体安全性。
|
1月前
|
监控 安全 测试技术
构建高效的精准测试平台:设计与实现指南
在软件开发过程中,精准测试是确保产品质量和性能的关键环节。一个精准的测试平台能够自动化测试流程,提高测试效率,缩短测试周期,并提供准确的测试结果。本文将分享如何设计和实现一个精准测试平台,从需求分析到技术选型,再到具体的实现步骤。
144 1
|
2月前
|
人工智能 监控 测试技术
云应用开发平台测试
云应用开发平台测试
79 2
|
1月前
|
监控 安全 测试技术
构建高效精准测试平台:设计与实现全攻略
在软件开发过程中,精准测试是确保产品质量的关键环节。一个高效、精准的测试平台能够自动化测试流程,提高测试覆盖率,缩短测试周期。本文将分享如何设计和实现一个精准测试平台,从需求分析到技术选型,再到具体的实现步骤。
68 0
|
10天前
|
监控 JavaScript 测试技术
postman接口测试工具详解
Postman是一个功能强大且易于使用的API测试工具。通过详细的介绍和实际示例,本文展示了Postman在API测试中的各种应用。无论是简单的请求发送,还是复杂的自动化测试和持续集成,Postman都提供了丰富的功能来满足用户的需求。希望本文能帮助您更好地理解和使用Postman,提高API测试的效率和质量。
54 11
|
1月前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
65 3