打开PGM图像16 BPP

Open a pgm image 16 bpp

本文关键字:BPP 图像 PGM 打开      更新时间:2023-10-16

我需要将每个像素16位的PGM图像转换为每个像素8位PGM图像8位,但是我有读取PGM Image 16 BPP的问题,而我不明白我的内容我做错了。这里的代码:

#include "pgm.h"
#include <iterator>
#include <algorithm>
#include <fstream>
#include <sstream>
using namespace std;
bool convert16to8bit(const std::string& inFilename, mat<uint8_t>& img, const std::string& outFilename){
    mat<uint16_t> imgTemp;
    ifstream is(inFilename, ios::binary);
    if (!is)
        return false;
    string magic;
    is >> magic;
    if (magic != "P2" && magic != "P5")
        return false;
    size_t rows, cols, nlevels;
    is >> cols >> rows >> nlevels;
    if (nlevels < 255)
        return false;
    is.get();
    img = mat<uint8_t>(rows, cols);
    if (nlevels == 255){
        if (magic == "P5"){
            is.unsetf(ios::skipws);
            img.data_.assign(istream_iterator<uint8_t>(is), istream_iterator<uint8_t>());
        }else
            img.data_.assign(istream_iterator<int>(is), istream_iterator<int>());
    }
    else{
        imgTemp = mat<uint16_t>(rows, cols);
        if (magic == "P5"){
            is.unsetf(ios::skipws);
            imgTemp.data_.assign(istream_iterator<uint16_t>(is), istream_iterator<uint16_t>());
        }
        else
            imgTemp.data_.assign(istream_iterator<int>(is), istream_iterator<int>());
        for (size_t r = 0; r < rows; r++)
            for (size_t c = 0; c < cols; c++)
                img(r, c) = imgTemp(r, c);
    }
    stringstream ss; 
    ss << outFilename << ".pgm";
    ofstream os(ss.str(), ios::binary);
    if (!os)
        return false;
    os << magic <<"n" << cols << " " << rows << "n255n";
    if (magic == "P2") 
        copy(begin(img), end(img), ostream_iterator<int>(os, " ")); 
    else 
        copy(begin(img), end(img), ostream_iterator<uint8_t>(os));
    return true;
}

//mat.h
#if !defined MAT_H 
#define MAT_H
#include <vector>
template <typename T> 
struct mat {
    size_t rows_, cols_; 
    std::vector<T> data_;
    mat(size_t rows = 0, size_t cols = 0) : rows_(rows), cols_(cols), data_(rows*cols) {}
    const size_t rows() const { return rows_; } 
    const size_t cols() const { return cols_; }
    const T& operator()(size_t r, size_t c) const { return data_[r*cols_ + c]; } 
    T& operator()(size_t r, size_t c) { return data_[r*cols_ + c]; }
    auto begin() -> decltype(data_.begin()) { return data_.begin(); } 
    auto end() -> decltype(data_.end()) { return data_.end(); } 
    auto begin() const -> decltype(data_.begin()) { return data_.begin(); } 
    auto end() const -> decltype(data_.end()) { return data_.end(); }
};
#endif // MAT_H

此代码试图执行IMG(r,c(= imgtemp(r,c((错误:vector sibscript用PGM 16BPP(执行错误,但使用PGM 8BPP我可以打开它没有问题,并将其重新创建为原始的,没有错误。我认为问题与istream_iterator&lt;uint16_t>因为istream_iterator&lt;uint8_t>工作(带有PGM 8bit(。有任何解决方案吗?

感谢您的任何帮助

我找到了解决问题的方法。如果对某人有用,这是正确的代码:

#include "pgm.h"
#include <iterator>
#include <algorithm>
#include <fstream>
#include <sstream>
using namespace std;
bool convert16to8bit(const std::string& inFilename, mat<uint8_t>& img, const std::string& outFilename){
    mat<uint16_t> imgTemp;
    ifstream is(inFilename, ios::binary);
    if (!is)
        return false;
    string magic;
    is >> magic;
    if (magic != "P2" && magic != "P5")
        return false;
    size_t rows, cols, nlevels;
    is >> cols >> rows >> nlevels;
    if (nlevels < 255)
        return false;
    is.get();
    img = mat<uint8_t>(rows, cols);
    if (nlevels == 255){
        if (magic == "P5"){
            is.unsetf(ios::skipws);
            img.data_.assign(istream_iterator<uint8_t>(is), istream_iterator<uint8_t>());
        }else
            img.data_.assign(istream_iterator<int>(is), istream_iterator<int>());
    }
    else{
        imgTemp = mat<uint16_t>(rows, cols);
        if (magic == "P5"){
            //here is the line changed
            is.read(reinterpret_cast<char *>(&imgTemp.data_[0]), imgTemp.rows()*imgTemp.cols() * 2);          
        }
        else
            imgTemp.data_.assign(istream_iterator<int>(is), istream_iterator<int>());
        for (size_t r = 0; r < rows; r++)
            for (size_t c = 0; c < cols; c++)
                img(r, c) = imgTemp(r, c);
    }
    stringstream ss; 
    ss << outFilename << ".pgm";
    ofstream os(ss.str(), ios::binary);
    if (!os)
        return false;
    os << magic <<"n" << cols << " " << rows << "n255n";
    if (magic == "P2") 
        copy(begin(img), end(img), ostream_iterator<int>(os, " ")); 
    else 
        copy(begin(img), end(img), ostream_iterator<uint8_t>(os));
    return true;
}