RGB源数据操作:图片顺时针90°旋转

简介: RGB源数据操作:图片顺时针90°旋转

一、运行环境介绍

Linux系统: Redhat6.3 (32位)


gcc 版本 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC)


二、功能介绍

打开一张BMP图片,实现顺时针90°旋转后生成一张新的图片。


三、核心代码

可以传入任意尺寸的BMP图片进行生成旋转。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#pragma pack(1) //强制1个字节对齐
//BMP的文件头
struct _BMP_HEAD
{
    char type[2]; //图片的类型 "BM"
    unsigned int size; //文件大小
    unsigned short  r1; //保留1
    unsigned short  r2; //保留2
    unsigned int seek; //数据偏移字节(真实像素点数据)
};
//BMP的参数信息
struct _BMP_INFO
{
    unsigned int size; //当前结构体大小
    unsigned int w; //宽度
    unsigned int h; //高度
    unsigned short flag; //固定为1
    unsigned short bit; //像素点的位数
    unsigned int r1; //压缩方式  0
    unsigned int r2; //水平分辨率
    unsigned int r3; //垂直分辨率
    unsigned int r4; //垂直分辨率
    unsigned int r5; //引用色彩
    unsigned int r6; //关键色彩
};
int main(int argc,char **argv)
{
    int cnt;
    if(argc!=3)
    {
        printf("传入的参数格式: ./a.out <原图片的名称> <新图片的名称>\n");
        return 0;
    }
    /*1. 打开原图片*/
    FILE *src_fp=fopen(argv[1],"rb");
    if(src_fp==NULL)
    {
        printf("%s 图片打开失败.\n",argv[1]);
        return 0;
    }
    /*2. 读取图片的头信息*/
    struct _BMP_HEAD src_bmp_head;
    cnt=fread(&src_bmp_head,1,sizeof(struct _BMP_HEAD),src_fp);
    printf("原图片头读取%d字节.\n",cnt);
    printf("原图片类型:%c%c.\n",src_bmp_head.type[0],src_bmp_head.type[1]);
    printf("原文件大小:%d.\n",src_bmp_head.size);
    printf("原文件的数据偏移量:%d.\n",src_bmp_head.seek);
    /*3. 读取图片的参数信息*/
    struct _BMP_INFO src_bmp_info;
    cnt=fread(&src_bmp_info,1,sizeof(struct _BMP_INFO),src_fp);
    printf("原图片参数结构读取%d字节.\n",cnt);
    printf("原图片宽:%d\n",src_bmp_info.w);
    printf("原图片高:%d\n",src_bmp_info.h);
    printf("原图片像素位:%d\n",src_bmp_info.bit);
    /*4. 创建一张新的BMP图片*/
    FILE *new_fp=fopen(argv[2],"wb");
    if(new_fp==NULL)
    {
        printf("%s 文件创建失败.\n",argv[2]);
        return 0;
    }
    /*5. 创建BMP的文件头*/
    struct _BMP_HEAD new_bmp_head;
    memset(&new_bmp_head,0,sizeof(struct _BMP_HEAD));
    //图片的类型
    new_bmp_head.type[0]='B';
    new_bmp_head.type[1]='M';
    //文件大小
    new_bmp_head.size=54+src_bmp_info.w*src_bmp_info.h*3;
    //数据偏移量
    new_bmp_head.seek=54;
    //写文件头
    cnt=fwrite(&new_bmp_head,1,sizeof(struct _BMP_HEAD),new_fp);
    printf("新图片头成功写入:%d 字节.\n",cnt);
    /*6. 写文件参数信息*/
    struct _BMP_INFO new_bmp_info;
    memset(&new_bmp_info,0,sizeof(struct _BMP_INFO));
    //当前结构体大小
    new_bmp_info.size=sizeof(struct _BMP_INFO);
    //图片的宽度和高度
    new_bmp_info.w=src_bmp_info.h;
    new_bmp_info.h=src_bmp_info.w;
    //图片的颜色位数
    new_bmp_info.bit=24;
    //标志位
    new_bmp_info.flag=1;
    //写入文件参数信息
    cnt=fwrite(&new_bmp_info,1,sizeof(struct _BMP_INFO),new_fp);
    printf("新图片的参数结构成功写入:%d 字节.\n",cnt);
  //计算原图片宽度是否是4的倍数
  int one_line_byte=src_bmp_info.w*3;
  while(one_line_byte%4!=0)one_line_byte++;
  int val_byte=one_line_byte-src_bmp_info.w*3; //相差的字节数
  printf("原图片的宽度补齐%d字节.\n",val_byte);
  //计算新图片宽度是否是4的倍数
  int new_one_line_byte=new_bmp_info.w*3;
  while(new_one_line_byte%4!=0)new_one_line_byte++;
  int new_val_byte=new_one_line_byte-new_bmp_info.w*3; //相差的字节数
  printf("新图片的宽度补齐%d字节.\n",new_val_byte);
    /*7. 写入位图数据*/
    int w,h;
    int seek=0;
    int c=0;
    for(w=0;w<src_bmp_info.w;w++)
    {
        for(h=src_bmp_info.h;h>0;h--)
        {
            seek=h*one_line_byte+54-one_line_byte+w*3;
            //从头开始偏移
            fseek(src_fp,seek,SEEK_SET);
            fread(&c,1,3,src_fp); //读取图片数据
            fwrite(&c,1,3,new_fp); //写数据
        }
    if(new_val_byte)fwrite(&c,1,new_val_byte,new_fp); //如果需要补齐,就写补齐数据
    }
    /*8. 关闭文件*/
    fclose(new_fp);
    fclose(src_fp);
    return 0;
}

四、运行效果

原图片:

image.png

旋转之后的图片:

image.png

目录
相关文章
|
8月前
|
SQL 传感器 人工智能
生成更智能,调试更轻松,SLS SQL Copilot 焕新登场!
本文是阿里云日志服务(SLS)首次对外系统性地揭秘 SLS SQL Copilot 背后的产品理念、架构设计与核心技术积淀。我们将带你深入了解,这一智能分析助手如何从用户真实需求出发,融合前沿 AI 能力与 SLS 十余年日志分析最佳实践,打造出面向未来的智能化日志分析体验。
738 53
|
前端开发 JavaScript 关系型数据库
基于Python+Vue开发的商城管理系统源码+运行步骤
基于Python+Vue开发的商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Python编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Python的网上商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
533 7
|
8月前
|
人工智能
四大公益场景,20万奖金!AI开源公益创新挑战赛邀你一起「小有可为」
四大公益场景,20万奖金!AI开源公益创新挑战赛邀你一起「小有可为」
477 8
|
SQL 调度 数据库
开发YashanDB数据库?用 DBeaver for YashanDB 更顺手
数据库开发复杂易错,尤其在企业级场景中。为提升效率,YashanDB 团队基于 DBeaver 开源工具打造专属解决方案——DBeaver for YashanDB。它支持多类型数据库对象管理(表、视图、函数等),适配 YashanDB 特有表结构(HEAP、LSC),提供智能补全、语法高亮、SQL 调试等功能,让开发更高效流畅。推荐用于数据库应用开发团队、高频调试用户及中大型企业统一工具栈场景。
|
机器学习/深度学习 监控 数据可视化
DeepSeek模型解释与可视化
深度学习模型常被视为“黑盒”,其决策过程难以理解,但在医疗、金融等高风险领域,理解模型决策至关重要。DeepSeek提供多种工具和方法,帮助解释和可视化模型的决策过程。本文介绍如何使用DeepSeek进行特征重要性分析、中间层可视化、局部解释(如LIME和SHAP)及训练过程监控,并通过代码示例详细讲解这些技巧,助力你掌握模型解释与可视化的方法。
|
缓存 数据挖掘 API
淘宝商品类目API的获取与应用探索
淘宝商品类目API是淘宝开放平台提供的关键服务,允许开发者获取淘宝商品的类目信息,包括根类目、子类目及属性信息。本文介绍API的获取方法、应用场景及使用技巧,帮助电商从业者和开发者更好地利用类目数据,提升商品管理、搜索推荐及数据分析等能力。
954 1
|
机器学习/深度学习 数据采集 算法
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
这篇博客文章介绍了如何使用包含多个网络和多种训练策略的框架来完成多目标分类任务,涵盖了从数据准备到训练、测试和部署的完整流程,并提供了相关代码和配置文件。
678 0
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
|
机器学习/深度学习 人工智能 算法
机器学习实战:用Python和Scikit-Learn构建分类器
机器学习在当今科技领域发挥着越来越重要的作用,而构建分类器是其中的一项关键任务。本文将带你进入机器学习的世界,通过使用Python编程语言和Scikit-Learn库,实际动手构建一个分类器。我们将探讨机器学习的基本概念、数据准备、模型训练以及评估分类器性能的方法。
|
机器学习/深度学习 人工智能 算法
王道考研操作系统同步与互斥(王道大题详解)(二)
王道考研操作系统同步与互斥(王道大题详解)(二)
548 0
王道考研操作系统同步与互斥(王道大题详解)(二)