我有一个tga图像,我想在不使用库的情况下将其大小调整为其一半大小,现在我正尝试将其他像素添加到新的像素向量中,但它对我来说并不像听起来那么简单,这是我第一次使用c ++进行编码。
我有一个名为RGB的类,该类为4个整数,其值分别为R,G,B和A。Ive尝试了经典的处理方式,即我只是将新像素向量中的一个位置告诉一个像素,就像旧像素的向量。 Ive还使用了可与std向量一起使用的“插入”方法。
我已经使用数字5作为向量中的假设位置。
std::vector<RGB> Pixels;
std::vector<RGB> newPixels;
// Heres a bunch of code filling up the Pixel one from loaded in data.
newPixels.insert(5, Pixels[5]);
给我错误:
error: no matching function for call to ‘std::vector<RGB>::insert(int, __gnu_cxx::__alloc_traits<std::allocator<RGB> >::value_type&)’
newPixels.insert(5, Pixels[5]);
newPixels[5] = Pixels[5];
给我错误
Segmentation fault (core dumped)
这就是我将RGB添加到第一个矢量的方式
std::uint8_t* BuffPos = ImageData.data();
Pixels[(height - 1 - I) * width + J].RGBA.B = *(BuffPos++);
Pixels[(height - 1 - I) * width + J].RGBA.G = *(BuffPos++);
Pixels[(height - 1 - I) * width + J].RGBA.R = *(BuffPos++);
Pixels[(height - 1 - I) * width + J].RGBA.A = (BitsPerPixel > 24 ? *(BuffPos++) : 0xFF);
这是需要更多信息的人员的完整代码。
#include <iostream>
#include <stdio.h>
#include <vector>
#include <stdexcept>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
typedef union RGB
{
std::uint32_t Color;
struct
{
std::uint8_t B, G, R, A;
} RGBA;
} *PRGB;
class Tga
{
private:
std::vector<RGB> Pixels;
bool ImageCompressed;
std::uint32_t width, height, size, BitsPerPixel;
public:
Tga(const char* FilePath);
void Save(const char* FilePath);
void Resize();
};
Tga::Tga(const char* FilePath)
{
std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
if (!hFile.is_open()){throw std::invalid_argument("File Not Found.");}
std::uint8_t Header[18] = {0};
std::vector<std::uint8_t> ImageData;
static std::uint8_t DeCompressed[12] = {0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
static std::uint8_t IsCompressed[12] = {0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
hFile.read(reinterpret_cast<char*>(&Header), sizeof(Header));
if (!std::memcmp(DeCompressed, &Header, sizeof(DeCompressed)))
{
BitsPerPixel = Header[16];
width = Header[13] * 0xFF + Header[12];
height = Header[15] * 0xFF + Header[14];
size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
if ((BitsPerPixel != 24) && (BitsPerPixel != 32))
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image.");
}
ImageData.resize(size);
ImageCompressed = false;
hFile.read(reinterpret_cast<char*>(ImageData.data()), size);
}
else if (!std::memcmp(IsCompressed, &Header, sizeof(IsCompressed)))
{
BitsPerPixel = Header[16];
width = Header[13] * 0xFF + Header[12];
height = Header[15] * 0xFF + Header[14];
size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
if ((BitsPerPixel != 24) && (BitsPerPixel != 32))
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image.");
}
RGB Pixel = {0};
int CurrentByte = 0;
std::size_t CurrentPixel = 0;
ImageCompressed = true;
std::uint8_t ChunkHeader = {0};
int BytesPerPixel = (BitsPerPixel / 8);
ImageData.resize(width * height * sizeof(RGB));
do
{
hFile.read(reinterpret_cast<char*>(&ChunkHeader), sizeof(ChunkHeader));
if(ChunkHeader < 128)
{
++ChunkHeader;
for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel)
{
hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel);
ImageData[CurrentByte++] = Pixel.RGBA.B;
ImageData[CurrentByte++] = Pixel.RGBA.G;
ImageData[CurrentByte++] = Pixel.RGBA.R;
if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.RGBA.A;
}
}
else
{
ChunkHeader -= 127;
hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel);
for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel)
{
ImageData[CurrentByte++] = Pixel.RGBA.B;
ImageData[CurrentByte++] = Pixel.RGBA.G;
ImageData[CurrentByte++] = Pixel.RGBA.R;
if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.RGBA.A;
}
}
} while(CurrentPixel < (width * height));
}
else
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit TGA File.");
}
hFile.close();
std::uint8_t* BuffPos = ImageData.data();
Pixels.resize(width * height);
//Flip the pixels and store them in my vector..
for (std::size_t I = 0; I < height; ++I)
{
for (std::size_t J = 0; J < width; ++J)
{
// cout << "This is pixel :" << ((height - 1 - I) * width + J);
// cout << "This is B :" + BuffPos;
Pixels[(height - 1 - I) * width + J].RGBA.B = *(BuffPos++);
// cout << "This is G :" + BuffPos;
Pixels[(height - 1 - I) * width + J].RGBA.G = *(BuffPos++);
// cout << "This is R :" + BuffPos;
Pixels[(height - 1 - I) * width + J].RGBA.R = *(BuffPos++);
Pixels[(height - 1 - I) * width + J].RGBA.A = (BitsPerPixel > 24 ? *(BuffPos++) : 0xFF);
}
if(BitsPerPixel == 24)
BuffPos += (-width * 3) & 3;
}
}
void Tga::Save(const char* FilePath)
{
std::fstream hFile(FilePath, std::ios::out | std::ios::binary);
if (!hFile.is_open()) {throw std::invalid_argument("Cannot open file for writing.");}
std::vector<std::uint8_t> ImageData(size);
std::uint8_t* BuffPos = ImageData.data();
//Flip it back to how it was when we loaded it..
for (std::size_t I = 0; I < height; ++I)
{
for (std::size_t J = 0; J < width; ++J)
{ //Flip The ScanLines/Rows back to normal.
*(BuffPos++) = Pixels[(height - 1 - I) * width + J].RGBA.B;
*(BuffPos++) = Pixels[(height - 1 - I) * width + J].RGBA.G;
*(BuffPos++) = Pixels[(height - 1 - I) * width + J].RGBA.R;
if (BitsPerPixel > 24)
*(BuffPos++) = Pixels[(height - 1 - I) * width + J].RGBA.A;
}
if(BitsPerPixel == 24)
BuffPos += (-width * 3) & 3;
}
static std::uint8_t DeCompressed[12] = {0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
static std::uint8_t IsCompressed[12] = {0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
if (!ImageCompressed)
{
hFile.write(reinterpret_cast<char*>(&DeCompressed), sizeof(DeCompressed));
hFile.put((width & 0xFF));
hFile.put((width & 0xFF) / 0xFF);
hFile.put((height & 0xFF));
hFile.put(((height & 0xFF) / 0xFF));
hFile.put(BitsPerPixel);
hFile.put(0x0);
hFile.write(reinterpret_cast<char*>(ImageData.data()), ImageData.size());
hFile.close();
}
else
{
hFile.write(reinterpret_cast<char*>(&IsCompressed), sizeof(IsCompressed));
hFile.put((width & 0xFF));
hFile.put((width & 0xFF) / 0xFF);
hFile.put((height & 0xFF));
hFile.put(((height & 0xFF) / 0xFF));
hFile.put(BitsPerPixel);
hFile.put(0x0);
}
hFile.close();
}
void Tga::Resize()
{
std::vector<RGB> newPixels;
int thumbwidth = 50;
int thumbheight = 50;
for (int f = 0; f < thumbheight; f++) // y on output
{
for (int g = 0; g < thumbwidth; g++) // x on output
{
newPixels.insert(newPixels.begin() + 5, Pixels[5]);
// newPixels[5] = Pixels[5];
}
}
// Pixels = newPixels;
// width = thumbwidth;
// height = thumbheight;
// size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
}
int main()
{
cout << "Hello, World!";
Tga picture = Tga("Black.tga");
cout << "woooooooooooooooooooooooooooooooooooooooooooow";
picture.Resize();
// cout << "2222222222222222222222222222222222222222222222222222222222222";
// picture.Save("newBlack.tga");
}