• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Klasa operująca na bmp

Object Storage Arubacloud
0 głosów
112 wizyt
pytanie zadane 6 lipca 2020 w C i C++ przez loki4 Nowicjusz (120 p.)

Dzień dobry,

mam napisać klasę operującą na bmp i dla wygody pixele muszą mieścić w jakiejkolwiek strukturze dwuwymiarowej. Wybrałam wektor, ale niestety pojawia się błąd podczas wykonywania. Co robię źle?

#ifndef IMAGE_H
#define IMAGE_H
#include <string>
#include <vector>
#include <cstdint>

class image
{
    public:
        image(std::string filePath);

        virtual ~image();
        struct BITMAPFILEHEADER
        {
            short bfType;
            int bfSize;
            short bfReserved1;
            short brReserved2;
            int bfOffbits;
        };
        struct BITMAPINFOHEADER
        {
            int biSize;
            int biWidth;
            int biHeight;
            short biPlanes;
            short biBitcount;
            int biCopression;
            int biSizeImage;
            int biXPixelPerMeter;
            int biYPixelPerMeter;
            int biClrUsed;
            int biClrImportant;
        };
        std::vector <std::vector <uint8_t> > Pixels;
    protected:

    private:
};
#endif // IMAGE_H
#include "image.h"
#include <fstream>
#include <iostream>

using namespace std;

image::~image()
{
}

image::image(string filePath)
{
   ifstream fileImage;
   fileImage.open(filePath.c_str(), ios::binary);
   if(!fileImage.good())
        {
         throw runtime_error("błąd otwarcia pliku!");
        }
    char* temp = new char[sizeof(BITMAPFILEHEADER)];
    fileImage.read(temp, sizeof(BITMAPFILEHEADER));

    BITMAPFILEHEADER* fileHeader = (BITMAPFILEHEADER*)(temp);

    temp = new char[sizeof(BITMAPINFOHEADER)];
    fileImage.read(temp, sizeof(BITMAPINFOHEADER));

    BITMAPINFOHEADER* infoHeader = (BITMAPINFOHEADER*)(temp);

    fileImage.seekg(fileHeader->bfOffbits, ios::beg);

    uint8_t bTemp;
    temp = new char[1];
    for (int i = 0; i < infoHeader->biHeight;i++)
    {
        for(int j = 0; j < infoHeader->biWidth; j++)
        {
            fileImage.read(temp, sizeof(uint8_t));
            bTemp = (uint8_t)atoi(temp);
            Pixels[i].push_back(bTemp);
        }
    }
}
#include "image.h"
#include <iostream>

using namespace std;
int main()
{
    image obraz("lena.bmp");
    return 0;
}

Obrazek na którym ćwiczę: obrazek.bmp

2 odpowiedzi

+1 głos
odpowiedź 6 lipca 2020 przez adrian17 Ekspert (344,860 p.)
Pixels[i].push_back(bTemp);

Nigdzie nie robisz push_back lub resize na zewnętrznym vectorze.

bTemp = (uint8_t)atoi(temp);

Nie rozumiem też, czemu próbujesz parsować bajt obrazu jako tekst z liczbą.

0 głosów
odpowiedź 6 lipca 2020 przez j23 Mędrzec (194,920 p.)
edycja 6 lipca 2020 przez j23

Ktoś tu chyba nie ogarnia do końca wskaźników ;) Po co tam to new?

Zamiast pisać:

char* temp = new char[sizeof(BITMAPFILEHEADER)];
fileImage.read(temp, sizeof(BITMAPFILEHEADER));

BITMAPFILEHEADER* fileHeader = (BITMAPFILEHEADER*)(temp);

wystarczy:

BITMAPFILEHEADER fileHeader;

fileImage.read(reinterpret_cast<char*>(&fileHeader), sizeof(BITMAPFILEHEADER));

Nie ma new i nie ma wycieków pamięci. To samo robisz z resztą alokacji via new, bo są one kompletnie zbędne.

Co do czytania samej bitmapy, to robisz to źle - wiersze są wyrównane do 4 bajtów, czyli bitmapa RGB8 o szerokości 3 pikseli nie będzie miała wiersza o wielkości 9 bajtów, ale 12 (3 bajty wyrównania na końcu). Zresztą zakładasz też, że bitmapa zawsze jest 8-bitowa (ta z kolei posiada paletę, której nie czytasz).

std::vector <std::vector <uint8_t> > Pixels;

Lepiej użyj std::vector <RGBTRIPLE> do trzymania całej bitmapy.

Podobne pytania

0 głosów
1 odpowiedź 477 wizyt
0 głosów
0 odpowiedzi 238 wizyt
pytanie zadane 28 marca 2021 w Mikrokontrolery przez francus11 Gaduła (3,250 p.)
0 głosów
1 odpowiedź 332 wizyt
pytanie zadane 16 stycznia 2020 w C i C++ przez Igor Użytkownik (740 p.)

92,568 zapytań

141,420 odpowiedzi

319,622 komentarzy

61,954 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...