使用C ++将bmp照片旋转90度 [英] stuck in rotating a bmp photo 90 degrees using C++

查看:233
本文介绍了使用C ++将bmp照片旋转90度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码,它破坏了照片我不知道为什么!

**它是一个24位的位图**



< pre lang =c ++> #include < < span class =code-leadattribute> iostream >
#include < fstream >
使用 命名空间 std ;
int main()
{
fstream flower( < span class =code-string> flower.bmp,ios :: in | ios :: out | ios :: binary);
// 声明一个包含数据字节的数组属于800 * 686像素:
char temp [ 686 * 800 * 3 ]; // * 3因为每个像素包含3个字节。

flower.seekg ( 54 ,ios :: beg); // 花的第54个字节(bmp文件)属于标题,像素数据在此之后开始)
flower.read(temp, 686 * 3 * 800 ); // 将像素字节分配给数组:
// 交换位图文件的宽度和高度:
flower.seekg( 18 ,ios :: beg); // 19,20,21 ,22个字节定义bmp文件的宽度,它是一个整数,接下来的4个字节属于高度。
char read1 [ 4 ];
char read2 [ 4 ];
flower.read(read1, 4 );
flower.read(read2, 4 );
flower.seekg( 22 ,ios :: beg);
flower.write(read1, 4 );
flower.seekg( 18 ,ios :: beg);
flower.write(read2, 4 );
// 用高度字节交换宽度字节。
flower.seekg(< span class =code-digit> 54
,ios :: beg);
int k = 0 ;
int l = 0 ;
for int i = 1 ; i< = 686 ; i ++)
{
flower.seekg(54 + k,ios :: beg);
for int j = 1 ; j< = 800 ; j ++)
{
flower.put(temp [l]);
flower.seekg( 1 );
flower.put(temp [++ l]);
flower.seekg( 1 );
flower.put(temp [++ l]);
l ++;
flower.seekg( 685 * 3 );
}
k + = 3 ;
}
flower.close();
}

解决方案

你必须考虑到位图在 32 32 位(即四个字节)边界(填充)。宽度 800 的原始位图不需要填充(因此大小正好是 1646454 字节)图像需要它( 686%4 非零),即你需要为每个添加 2 填充字节行(因此文件大小 1648054 ,即 800x2 比原始文件长)。

以下代码旋转原始图像,将结果写入' rflower.bmp '文件。

  #include   <   iostream  >  
#include < fstream >
#include < stdint.h >
使用 命名空间标准;
int main()
{
const int BFHS = 14 ; // 位图文件标题大小
const int BIHS = 40 ; // 位图信息标题大小
const int W = 800 ;
const int H = 686 ;

ifstream bmp( flower.bmp,ios :: binary) ;
ofstream rbm( rflower.bmp,ios :: binary);
char head [BFHS + BIHS];
char rgb [ 3 * W * H];

// 复制标题
bmp.read(head ,BFHS + BIHS);
// 交换宽度与高度
uint32_t temp = *(uint32_t *) &安培;头[BFHS + 4];
*(uint32_t *)& head [BFHS + 4] = *(uint32_t *)& head [BFHS + 8];
*(uint32_t *)& head [BFHS + 8] = temp;
rbm.write(head,BFHS + BIHS);
// 读取像素值
bmp.read(rgb, 3 * W * H);

char 零[ 3 ] = { 0 };

for int y = 0 ; y< W; ++ y)
{
for int x = 0 ; x< H; ++ x)
{
// rbm(x,y)是原始bmp(y,H-1-x)
rbm.write(& rgb [ (H - x - 1 )* W * 3 + y * 3 ], 3 );
}
rbm.write(零, 2 ); // 32位边界对齐
}
}


通过以下基于零的索引转换完成将矩阵旋转90度:

 A = N x M原始矩阵
B = M×N变换矩阵(即旋转+90度)
A [i,j] - > B [M-j-1,i]

因此,您将数据读入内存中的原始矩阵,在内存中创建转换矩阵,并将原始单元转换为转换后的矩阵。最后,将数据从内存写入文件(带有相应的标题和填充字节)。



干杯

Andi



PS:请注意,位图文件中的每一行都填充为4个字节的倍数!


如果您正在编写Windows代码您可以使用.Net库来帮助您:

旋转图像 [ ^ ]然后它适用于任何图片。



如前所述,使用硬编码值并不好,它们应该是您方法的参数。



同样使用十六进制编辑器可以帮助您查看文件的真实外观。


here's my code, it corrupts the photo i donno why!
** its a 24-bit bitmap **

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
	fstream flower("flower.bmp", ios::in | ios::out | ios::binary);
	//declaring an array which holds data bytes belong to 800*686 pixels:
	char temp[686*800*3]; // *3 because each pixel contains 3 bytes.
	
	flower.seekg(54,ios::beg); //first 54 bytes of flower (bmp file) belong to the headers, pixels data start after that)
	flower.read(temp,686*3*800);//assigning pixel bytes to the array:
	//swapping width and height of the bitmap file:
	flower.seekg(18,ios::beg);//19,20,21,22 bytes defines the width of bmp file which is an integer and next 4 bytes belong to the height.
	char read1[4];
	char read2[4];
	flower.read(read1,4);
	flower.read(read2,4);
	flower.seekg(22,ios::beg);
	flower.write(read1,4);
	flower.seekg(18,ios::beg);
	flower.write(read2,4);
	//swapping width bytes with height bytes.
	flower.seekg(54,ios::beg);
	int k=0;
        int l=0;
	for(int i=1;i<=686;i++)
	{
		flower.seekg(54+k,ios::beg);
		for(int j=1;j<=800;j++)
		{
			flower.put(temp[l]);
			flower.seekg(1);
			flower.put(temp[++l]);
			flower.seekg(1);
			flower.put(temp[++l]);
			l++;
			flower.seekg(685*3);
		}
		k+=3;
	}
	flower.close();
}

解决方案

You have to take into account that bitmaps have rows aligned on 32 bits (i.e four bytes) boundaries (they are padded). The original bitmap, having width 800 doesn't need padding (hence is size is exactly 1646454 bytes) while the rotated image needs it (686 % 4 is non-zero), that is you need to add 2 padding bytes per each row (hence the file size is 1648054, that is 800x2 longer than the original one).
The following code rotates the original image, writing the resulting one to the 'rflower.bmp' file.

#include<iostream>
#include<fstream>
#include <stdint.h>
using namespace std;
int main()
{
  const int BFHS = 14; // bitmap file header size
  const int BIHS = 40; // bitmap info header size
  const int W = 800;
  const int H = 686;

  ifstream bmp("flower.bmp", ios::binary);
  ofstream rbm("rflower.bmp", ios::binary);
  char head[BFHS+BIHS];
  char rgb[3*W*H];

  // copy the header
  bmp.read(head, BFHS+BIHS);
  // swap width with height
  uint32_t temp = *(uint32_t*)&head[BFHS+4];
 *(uint32_t*)&head[BFHS+4] = *(uint32_t*)&head[BFHS+8];
 *(uint32_t*)&head[BFHS+8]= temp;
  rbm.write(head, BFHS+BIHS);
  // read pixel values
  bmp.read(rgb, 3*W*H);

  char zero[3] = {0};

  for (int y=0; y<W; ++y)
  {
    for (int x=0; x<H; ++x)
    {
      // rbm (x,y) is original bmp (y,H-1-x)
      rbm.write(&rgb[(H - x - 1) * W * 3 + y * 3], 3);
    }
    rbm.write(zero,2); // align on 32 bit boundary
  }
}


Rotating a matrix by 90 degree is done by the following transformation of zero-based indices:

A = N x M original matrix
B = M x N transformed matrix (i.e. rotated by +90 degree)
A[i,j] -> B[M-j-1,i]

So, you read the data into the original matrix in memory, create a transformation matrix in memory, and do transform the original cells into the transformed matrix. Finally, write the data from memory to the file (with the appropriate header and padding bytes).

Cheers
Andi

PS: Note that each row in the bit map file is padded to a multiple of 4 bytes!


If you are writing code for windows you can use .Net library to help you:
Rotate image[^] then it will work for any image.

As already mentioned it is not good to use hard-coded values, they should be parameters to your method.

Also using a Hex Editor can help you see what the file really looks like.


这篇关于使用C ++将bmp照片旋转90度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆