将 RGB 图像保存为 PPM 格式
Save RGB image as PPM format
我正在尝试用 C++ 创建 RGB 图像。我没有使用任何像 OpenCv 这样的图像库。
首先,我尝试创建灰度图像。我想绘制矩形图像。我在函数中提供参数,如起点、宽度、高度等。此代码行适用于此灰度挑战,但我正在尝试将颜色通道增加到 3,如 RGB。然后,我正在设置红色、绿色和蓝色值,但它不起作用。这是我的问题。
如何正确工作?
- x => 起点 x 坐标
- y => y坐标的起点
- 宽度 => 矩形宽度
- 高度 => 矩形高度
- 值 => RGB 或灰度颜色值
我的代码
Image::Image(int width, int height, int n_channels, int step)
{
cout << "Image constructor is running!" << endl;
m_width = width;
m_height = height;
m_n_channels = n_channels;
m_step = m_width*m_n_channels;
if (m_step < step)
m_step = step;
m_data = new uchar[m_step*height];
}
Image* Image::new_gray(int width, int height)
{
cout << "New gray image is creating!" << endl;
return new Image(width, height, 1);
}
Image* Image::new_rgb(int width, int height)
{
cout << "New RGB image is creating!" << endl;
return new Image(width, height, 3);
}
void Image::set_rect(int x, int y, int width, int height, uchar value)
{
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
for (int j = y; j < y+height; ++j) {
if (j >= m_height)
break;
uchar* row_data = data(j);
for (int i = x; i < x+width; ++i) {
if (i >= m_width)
break;
for (int c = 0; c < m_n_channels; ++c)
if (c == 0) {
row_data[i*m_n_channels + c] = value;
} else if (c == 1) {
row_data[i*m_n_channels + c] = value;
} else if (c == 2) {
row_data[i*m_n_channels + c] = value;
}
}
}
}
bool Image::write_pnm(const std::string& filename) const
{
if (m_n_channels != 1) {
const string magic_head = "P6";
ofstream fout;
string extended_name = filename + ".ppm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
cout << reinterpret_cast<const char*>(row_data);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
const string magic_head = "P5";
ofstream fout;
string extended_name = filename + ".pgm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
我的主要功能
#include <cstdlib>
#include <iostream>
#include "image.h"
using std::cout;
using std::endl;
using ceng391::Image;
int main(int argc, char** argv)
{
Image* gray = Image::new_gray(128, 128);
cout << "(" << gray->w() << "x" << gray->h() << ") channels: "
<< gray->n_ch() << " step: " << gray->step() << endl;
gray->set_zero();
gray->set_rect(32, 32, 64, 64, 255);
gray->write_pnm("/tmp/test_image");
Image* rgb_image = Image::new_rgb(128,128);
cout << "(" << rgb_image->w() << "x" << rgb_image->h() << ") channels: "
<< rgb_image->n_ch() << " step: " << rgb_image->step() << endl;
rgb_image->set_zero_rgb();
rgb_image->set_rect(32, 32, 64, 64, 150);
rgb_image->write_pnm("/tmp/test_image_rgb");
delete gray;
delete rgb_image;
return EXIT_SUCCESS;
}
此代码适用于灰度图像,因为灰度图像具有与宽度相同的像素数。
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
但是当我想保存RGB图像时,像素数增加了3倍。一个像素通过 3 个通道表示,因此需要将一个像素的流大小乘以 3(R、G、B 通道)。
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar)*3);
我正在尝试用 C++ 创建 RGB 图像。我没有使用任何像 OpenCv 这样的图像库。
首先,我尝试创建灰度图像。我想绘制矩形图像。我在函数中提供参数,如起点、宽度、高度等。此代码行适用于此灰度挑战,但我正在尝试将颜色通道增加到 3,如 RGB。然后,我正在设置红色、绿色和蓝色值,但它不起作用。这是我的问题。
如何正确工作?
- x => 起点 x 坐标
- y => y坐标的起点
- 宽度 => 矩形宽度
- 高度 => 矩形高度
- 值 => RGB 或灰度颜色值
我的代码
Image::Image(int width, int height, int n_channels, int step)
{
cout << "Image constructor is running!" << endl;
m_width = width;
m_height = height;
m_n_channels = n_channels;
m_step = m_width*m_n_channels;
if (m_step < step)
m_step = step;
m_data = new uchar[m_step*height];
}
Image* Image::new_gray(int width, int height)
{
cout << "New gray image is creating!" << endl;
return new Image(width, height, 1);
}
Image* Image::new_rgb(int width, int height)
{
cout << "New RGB image is creating!" << endl;
return new Image(width, height, 3);
}
void Image::set_rect(int x, int y, int width, int height, uchar value)
{
if (x < 0) {
width += x;
x = 0;
}
if (y < 0) {
height += y;
y = 0;
}
for (int j = y; j < y+height; ++j) {
if (j >= m_height)
break;
uchar* row_data = data(j);
for (int i = x; i < x+width; ++i) {
if (i >= m_width)
break;
for (int c = 0; c < m_n_channels; ++c)
if (c == 0) {
row_data[i*m_n_channels + c] = value;
} else if (c == 1) {
row_data[i*m_n_channels + c] = value;
} else if (c == 2) {
row_data[i*m_n_channels + c] = value;
}
}
}
}
bool Image::write_pnm(const std::string& filename) const
{
if (m_n_channels != 1) {
const string magic_head = "P6";
ofstream fout;
string extended_name = filename + ".ppm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
cout << reinterpret_cast<const char*>(row_data);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
const string magic_head = "P5";
ofstream fout;
string extended_name = filename + ".pgm";
fout.open(extended_name.c_str(), ios::out | ios::binary);
fout << magic_head << "\n";
fout << m_width << " " << m_height << " 255\n";
for (int y = 0; y < m_height; ++y) {
const uchar *row_data = data(y);
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
}
fout.close();
return true;
}
我的主要功能
#include <cstdlib>
#include <iostream>
#include "image.h"
using std::cout;
using std::endl;
using ceng391::Image;
int main(int argc, char** argv)
{
Image* gray = Image::new_gray(128, 128);
cout << "(" << gray->w() << "x" << gray->h() << ") channels: "
<< gray->n_ch() << " step: " << gray->step() << endl;
gray->set_zero();
gray->set_rect(32, 32, 64, 64, 255);
gray->write_pnm("/tmp/test_image");
Image* rgb_image = Image::new_rgb(128,128);
cout << "(" << rgb_image->w() << "x" << rgb_image->h() << ") channels: "
<< rgb_image->n_ch() << " step: " << rgb_image->step() << endl;
rgb_image->set_zero_rgb();
rgb_image->set_rect(32, 32, 64, 64, 150);
rgb_image->write_pnm("/tmp/test_image_rgb");
delete gray;
delete rgb_image;
return EXIT_SUCCESS;
}
此代码适用于灰度图像,因为灰度图像具有与宽度相同的像素数。
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar));
但是当我想保存RGB图像时,像素数增加了3倍。一个像素通过 3 个通道表示,因此需要将一个像素的流大小乘以 3(R、G、B 通道)。
fout.write(reinterpret_cast<const char*>(row_data), m_width*sizeof(uchar)*3);