Twój kod ma inny błąd otóż coś zaczynasz czytać dane z pliku nie od tego miejsca co trzeba bo po małych testach dostawałem obraz z przesunięciem. Obliczyłem sobie to przesunięcie na podstawie pikseli i teraz po modyfikacjach już obraz wczytuje się nieco lepiej. Oto kod:
// readbitmap.cpp : Ten plik zawiera funkcję „main”. W nim rozpoczyna się i kończy wykonywanie programu.
//
#include <iostream>
#include <fstream>
using namespace std;
struct BITMAPFILEHEADER
{
int bfType;
int bfSize;
int bfReserved1;
int bfReserved2;
int bfOffBits;
};
struct BITMAPINFOHEADER
{
int biSize;
int biWidth;
int biHeight;
int biPlanes;
int biBitCount;
int biCompression;
int biSizeImage;
int biXpelsPerMeter;
int biYpelsPerMeter;
int biCrlUses;
int biCrlImportant;
};
struct kolor
{
unsigned char R;
unsigned char G;
unsigned char B;
};
void odczytaj_naglowek(fstream& obraz, BITMAPFILEHEADER& ob)
{
obraz.read(reinterpret_cast<char*>(&ob.bfType), 2);
obraz.read(reinterpret_cast<char*>(&ob.bfSize), 4);
obraz.read(reinterpret_cast<char*>(&ob.bfReserved1), 2);
obraz.read(reinterpret_cast<char*>(&ob.bfReserved2), 2);
obraz.read(reinterpret_cast<char*>(&ob.bfOffBits), 4);
}
int odczytaj_naglowek_obrazu(fstream& obraz, BITMAPINFOHEADER& ob)
{
obraz.read(reinterpret_cast<char*>(&ob.biSize), 4);
obraz.read(reinterpret_cast<char*>(&ob.biWidth), 4);
obraz.read(reinterpret_cast<char*>(&ob.biHeight), 4);
obraz.read(reinterpret_cast<char*>(&ob.biPlanes), 2);
obraz.read(reinterpret_cast<char*>(&ob.biBitCount), 2);
obraz.read(reinterpret_cast<char*>(&ob.biCompression), 4);
obraz.read(reinterpret_cast<char*>(&ob.biSizeImage), 4);
obraz.read(reinterpret_cast<char*>(&ob.biXpelsPerMeter), 4);
obraz.read(reinterpret_cast<char*>(&ob.biYpelsPerMeter), 4);
obraz.read(reinterpret_cast<char*>(&ob.biCrlUses), 4);
obraz.read(reinterpret_cast<char*>(&ob.biCrlImportant), 4);
return obraz.tellg();
}
int policz(int n)
{
if (n == 0) return 0;
else return policz(n - 1) + 3;
}
void odczytaj_obraz(fstream& obraz, unsigned char tab[], BITMAPINFOHEADER ob)
{
char* ch = new char[22 * 3];
obraz.read(ch, 22 * 3);
for (int i = 0; i < ob.biSizeImage / 3; i++)
{
obraz.read(reinterpret_cast<char*>(&tab[i]), 3);
}
obraz.clear();
}
void koloruj(unsigned char tab[], kolor tab_k[], BITMAPINFOHEADER ob)
{
for (int i = 0; i < ob.biSizeImage / 3; i++)
{
int k = tab[i];
if (k == 0)
{
tab_k[i].R = 0;
tab_k[i].G = 0;
tab_k[i].B = 0;
}
if (k > 0 && k < 86)
{
tab_k[i].R = policz(k);
tab_k[i].G = 0;
tab_k[i].B = 0;
}
if (k == 86)
{
tab_k[i].R = 255;
tab_k[i].G = 0;
tab_k[i].B = 0;
}
if (k > 86 && k < 171)
{
tab_k[i].R = 255;
tab_k[i].G = policz(k);
tab_k[i].B = 0;
}
if (k == 171)
{
tab_k[i].R = 255;
tab_k[i].G = 255;
tab_k[i].B = 0;
}
if (k > 171 && k < 256)
{
tab_k[i].R = 255;
tab_k[i].G = 255;
tab_k[i].B = policz(k);
}
}
}
void skopuj_obraz(fstream& obraz_src, fstream& obraz_des, kolor tab[], BITMAPINFOHEADER ob, BITMAPFILEHEADER ob1)
{
obraz_src.seekg(0);
obraz_des.seekg(0);
int k;
for (int i = 0; i < ob1.bfOffBits; i++)
{
obraz_src.read(reinterpret_cast<char*>(&k), 1);
obraz_des.write(reinterpret_cast<char*>(&k), 1);
}
for (int i = 0; i < ob.biSizeImage / 3; i++)
{
obraz_des.put(tab[i].B);
obraz_des.put(tab[i].G);
obraz_des.put(tab[i].R);
}
}
int main()
{
fstream obraz;
BITMAPFILEHEADER FileInfo;
BITMAPINFOHEADER PictureInfo;
obraz.open("sonar_aktywny_szary.bmp", ios::in | ios::binary);
if (!obraz)
{
cout << "Nie mozna otworzyc pliku!" << endl;
return 0;
}
odczytaj_naglowek(obraz, FileInfo);
odczytaj_naglowek_obrazu(obraz, PictureInfo);
unsigned char* pixmap;
pixmap = new unsigned char[PictureInfo.biSizeImage / 3];
kolor* kolormap;
kolormap = new kolor[PictureInfo.biSizeImage / 3];
odczytaj_obraz(obraz, pixmap, PictureInfo);
koloruj(pixmap, kolormap, PictureInfo);
fstream obraz_des;
obraz_des.open("sonar_aktywny_kolorowy2.bmp", ios::out | ios::binary);
if (!obraz_des)
{
cout << "Nie mozna otworzyc pliku!" << endl;
return 0;
}
skopuj_obraz(obraz, obraz_des, kolormap, PictureInfo, FileInfo);
obraz.close();
obraz_des.close();
return 0;
}
P.S. Nadal tutaj nie uwzględniam pikseli zerowych. Testowałem na bitmapie 700x466 i 699x466