Ich arbeite an einem C++ - Projekt - es soll Höhe, Breite und 10 beliebtesten Farben einer Bitmap finden. Das Finden von Höhe und Breite ist kein Problem, ich habe es innerhalb von Minuten gemacht, aber ich habe ernsthafte Probleme mit der Suche nach diesen Farben.C++ - 10 beliebtesten Farben einer Bitmap
Hier ist mein Code:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void main(int argc, char *argv[])
{
ifstream plik;
plik.open(argv[1]);
if (plik.good())
{
cout << "Bitmapa zaladowana poprawnie." << endl;
// Idziemy do 10 bajtu w pliku - tam jest zapisany numer bajtu pod ktorym zaczynaja sie informacje o pixelach
plik.seekg(10, ios::beg);
int adresPixeli = 0;
plik.read((char*)&adresPixeli, sizeof(int));
// Idziemy na 18 bajt w pliku (pod nim jest zapisana szerokosc, a od 22 jest wysokosc)
plik.seekg(18, ios::beg);
int szerokosc, wysokosc;
// Zapisujemy szerokosc do zmiennej szerokosc (w pixelach)
plik.read((char*)&szerokosc, sizeof(int));
plik.read((char*)&wysokosc, sizeof(int));
cout << "Szerokosc obrazu to: " << szerokosc << endl;
cout << "Wysokosc obrazu to: " << wysokosc << endl;
// Przejscie na 28 bajt w pliku, pod nim jest zapisana informacja o tym ile bitow ma kazdy pixel
plik.seekg(28, ios::beg);
int iloscBitow = 0;
// Read number of bytes used per pixel
plik.read((char*)&iloscBitow, sizeof(short int));
// Jesli mamy wysokosc i szerokosc to mozemy stworzyc tablice ktora bedzie przechowywac wartosci kolorow pixeli
// Rozmiar tablicy musi byc rowny szerokosc * wysokosc, a jeden pixel ma 3 bajty informacji
// RGB - red green blue, czyli informacje o kolorach (po 1 bajcie na red, green i blue)
// Alokacja pamieci dla tablicy ktora bedzie przechowywac wartosci bitow.
int *mapaPixeli = new int [szerokosc * wysokosc];
// Przejście do bajtu pod ktorym zaczynaja sie pixele
plik.seekg(adresPixeli, ios::beg);
// Zmienna do ktorej bedziemy wczytywac wartosc pixela (kolor - RGB, zapisany szesnastkowo np. 0xFFFFFF to kolor bialy, a
// 0x000000 to kolor czarny
// pozniej policzymy najczesciej wystepujace kolory i je wypiszemy
int wartoscPixela;
for (int i = 0; i < szerokosc * wysokosc; i++)
{
wartoscPixela = 0;
// Wczytujemy 3 bajty - bo na tylu zapisane sa informacje odnosnie 1 pixela, do zmiennej wartoscPixela
plik.read((char*)&wartoscPixela, 3);
// Zapisujemy wartosc w tablicy pixeli
if (iloscBitow == 24)
mapaPixeli[i] = wartoscPixela;
}
for (int i = 0; i < 100; i++)
cout << hex << mapaPixeli[i] << " ";
// Szukanie 10 najpopularniejszych kolorow
int max_count = 0;
int wynik;
// Przechowuje te elementy ktore juz zostaly policzone
vector<int> wartosciUnikalne;
// Sprawdza, czy element jest juz w wektorze wartosciUnikalne
bool czyJest = find(wartosciUnikalne.begin(), wartosciUnikalne.end(), 1) != wartosciUnikalne.end();
// Sprawdza czy wypisano juz 10 kolorow
int ileKolorow = 0;
cout << "Kody szesnastkowe 10 najpopularniejszych kolorow w bitmapie: to" << endl;
// Bedziemy wyliczac wystepowania 10 najczesciej powtarzajaych sie elementow
for (int ilosc = 0; ilosc < 10; ilosc++)
{
int max_count = 0;
for (int i = 0; i < szerokosc*wysokosc; i++)
{
// Sprawdza czy element jest w wartosciUnikalne
czyJest = find(wartosciUnikalne.begin(), wartosciUnikalne.end(), mapaPixeli[i]) != wartosciUnikalne.end();
int count = 1;
// Jesli nie ma elementu w wartosciUnikalne - liczy jego wystapienia
if (czyJest == false)
{
for (int j = i + 1; j<szerokosc*wysokosc; j++)
if (mapaPixeli[i] == mapaPixeli[j])
count++;
if (count>max_count)
max_count = count;
}
}
for (int i = 0; i < szerokosc*wysokosc; i++)
{
int count = 1;
czyJest = find(wartosciUnikalne.begin(), wartosciUnikalne.end(), mapaPixeli[i]) != wartosciUnikalne.end();
// Sprawdza czy jest element w wartosci unikalne, jesli nie ma - szuka aktualnie sprawdzanego elementu o najwiekszej
// ilosci wystapien i wypisuje go
if (czyJest == false)
{
for (int j = i + 1; j < szerokosc*wysokosc; j++)
if (mapaPixeli[i] == mapaPixeli[j])
count++;
if (count == max_count && ileKolorow <=10)
{
ileKolorow++;
wynik = mapaPixeli[i];
cout << hex << wynik << endl;
//cout << count << " " << max_count << endl;
wartosciUnikalne.push_back(wynik);
}
}
}
}
}
else
cout << "Nie udalo sie wczytac bitmapy." << endl;
system("PAUSE");
}
Diese Zeile:
plik.read((char*)&adresPixeli, sizeof(int));
Soll ja eine Adresse von Pixeln adresPixeli schreiben. Es ist am 10. Byte, so vor, dass ich gehen nur bis zum 10. Byte der Datei hier:
plik.seekg(10, ios::beg);
Und hier habe ich die Werte in ein Array lesen möchten genannt mapaPixeli, die genügend Speicher (Breite * Höhe) hat.
for (int i = 0; i < szerokosc * wysokosc; i++)
{
wartoscPixela = 0;
// Wczytujemy 3 bajty - bo na tylu zapisane sa informacje odnosnie 1 pixela, do zmiennej wartoscPixela
plik.read((char*)&wartoscPixela, 3);
// Zapisujemy wartosc w tablicy pixeli
if (iloscBitow == 24)
mapaPixeli[i] = wartoscPixela;
}
Das Problem ist:.. Es Werte nicht richtig lesen :(Ich weiß nicht, warum, und ich kann einen Fehler nicht gefunden Vielleicht werden einige von euch der Lage sein, mir dort zu helfen Auch gibt es eine Bedingung - es liest nur Pixel, wenn es 24 Bits ist (1 Pixel ist 24 Bits in meinem Fall), überprüfte es
Dann danach gibt es meinen eigenen Algorithmus, um 10 populärste Werte in einem Array zu finden, das funktioniert perfekt, aber hier funktioniert es nicht so, wie ich es gerne hätte, weil Pixelwerte nicht richtig gelesen werden
Ich glaube, Sie unterschätzen die Komplexität des BMP-Dateiformats https://en.wikipedia.org/wiki/BMP_file_format. Können Sie eine externe Bibliothek verwenden, um auf die Pixel zuzugreifen? –
Nein Ich kann keine externe Bibliothek verwenden. Das ist das Problem: Ja, ich habe diese Seite im Wiki schon einmal gelesen. Ich weiß, es ist ziemlich komplex, aber ich muss es irgendwie tun. – MindRoller
Sie werden verloren gehen, wenn Sie Code hetzen, ohne ein wenig darüber nachzudenken. Erstellen Sie eine geeignete Klasse, lesen Sie den Dateikopf mit der entsprechenden Struktur, speichern Sie Informationen in Elementvariablen, teilen Sie Ihren Code in separate logische Einheiten (verschiedene Funktionen) usw. Wie Alessandro Teruzzi sagte, ist das nicht so einfach. – Boiethios