Zdravim.
pls potreboval by som poradit ako mam zistit farbu pixela v borland builder.ide mi o to dat do podmienky ze ak sa farba pixela[x][y]==napriklad ciernej alebo este lepsie nejakemu rozmedziu jej odtiena(RGB),
nieco v tom zmysle ze if(Form1->Image1->Pixels[2][2]==ClBlack){......};
Fórum › C / C++
Zistenie farby pixela
no ten objekt o kterym mluvis (form1) by mel ukazovat na nejakou datovou oblast kde ma nahrany ten obrazek. a pokud vis jak je tam ten obrazek ulozen (tedy kolik polozek zabira jeden pixel a jak ho reprezentuji) muzes pomoci ukazatelu zjsitit barvy jednotlivych pixelu. ale tohle je dost hnusny a hlavne neportabilni reseni protoze si myslim ze takovyhle objekty se od sebe lisi a muze se lisit i jejich zpusob uschovy dat. mnohem elegantnejsi je to resit uz pri nacitani toho obrazku (kdyztak se koukni na tema Načítání BMP - Barvičky, je to docela podobne))
bmp = bitova mapa. ale to mas lepsi zjistovat uz pri nacitani pokud ten obekt do ktereho to nactes nema vestavenou nejakou funkci na porovnani/zjisteni barvy jednotlivych pixelu tak si myslim (nebo takhle : o zadne standardni funkci nevim. a je mnoho veci o kterych nevim) ze mas lepsi ten soubor proste precist byte po bytu a tam to kontrolovat
to:jura
to myslis v objekt inspektore??lebo som tam nic take nanasiel.som s toho akosi vykolajeny.ja som zacal s builderom len nedavno inak som robil len konzolove aplikacie ,a ani sa mu asi moc neplanujem venovat ja ho len len teraz potrebujem vyuzit pre lahko vytvoritelne okno a myslel som ze aj jednoduchu pracu z obrazkom
Mno, kdyz uz jsem neco podobneho pred chvilkou delal...
Rozhrani vypada nejak takhle..
Image img("test.bmp");
if(img[PX(0,0)] == Color(255,255,255)){
cout << "Je to bile!!!";
}
if(img[PX(0,0)] != Color(255,255,255)){
cout << "Neni to bile!!!";
}
class Color
{
public:
unsigned char r, g, b;
Color(unsigned char lr=0, unsigned char lg=0, unsigned char lb=0){
r = lr;
g = lg;
b = lb;
}
bool operator==(Color px){
if(r == px.r && g == px.g && b == px.b){
return true;
}
return false;
}
bool operator!=(Color px){
if(r == px.r && g == px.g && b == px.b){
return false;
}
return true;
}
};
class PX
{
public:
PX(unsigned int lx=0, unsigned int ly=0){
x = lx;
y = ly;
}
unsigned int x, y;
};
class Image
{
public:
Image(char *filename);
~Image();
Color operator[](PX p){
Color ret;
uint index = (p.y*width)+p.x;
ret.r = px[index].r;
ret.g = px[index].g;
ret.b = px[index].b;
return ret;
}
private:
Color *px;
unsigned int width, height, size;
};
Image::Image(char *filename){
FILE *fr;
fr = fopen(filename, "rb");
if(fr == NULL){
exit(1);
}
char buffer[50];
fread(&buffer, 1, 18, fr);
fread(&width, 1, 4, fr);
fread(&height, 1, 4, fr);
fread(&buffer, 1, 28, fr);
size = width*height;
px = new Color[size]();
for(unsigned int y=0; y<height; y++){
for(unsigned int x=0; x<width; x++){
fread(&px[(y*width)+x].b, 1, 1, fr);
fread(&px[(y*width)+x].g, 1, 1, fr);
fread(&px[(y*width)+x].r, 1, 1, fr);
}
fread(&buffer, 1, 2, fr);
}
fclose(fr);
}
Image::~Image(){
delete [] px;
}
BTW. da se nejak pretizit "[][]"???
To Zelenáč :
Jistěže. Budeš vracet referenci, kde máš uložený řádek(sloupec) toho objektu a u něj zase přetížíš operátor [].Nicměně, pokud můžu poradit - vyser se na to, přetěž funkční operátor, ušetříš si tím dost práce a nervů.
Koukám, že už ani psát nemužu. Abych dořekl myšlenku. Budeš mít třídu, která bude obalovat jednorozměrné pole = řádek matice, treba CRows. Této třídě přetížíš operátor [] tak, aby vracel už konkrétní hodnotu. Dále budeš mít třídu, která bude obsahovat obalené pole objektů CRows, této třídě zase přetižíš operátor [], který bude vracet REFERENCI na objekt typu CRows.
A když se ti bude hodne chtít, tak to mužeš udělat jako template,kterému předáš tu samopu třídu jen už s konkrétním typem a tím znova vymyslíš STL kontejner vector a použiješ std::vector<std::vector<Color> > Pixels.
ale myslim ze [][] ma uz implicitni funkcnost docela spolehlivou, takze neni potreba ho pretezovat (pokud se clovek snazi dodrzovat zasady slusneho psani kodu (teda, ta zasada je jen jedna: nepsat jako prase)), jako operator "pro matici" funguje i na user-defined typy
p.s.: vite ze a[i] == i[a] ?))
rikali sme si s kamosem ze napisem supr prasackej kod, kterej by ale fungoval... c by na to bylo idealni:
...
while( a[i][c][d][bf][f] == c[i][d][bf][d][a]){
for(int i=0, a=4,c=5;a=c;break);
while('k'!='z')break;
break;
continue;
return a;
}
...
a tak dal)
Kdepak... Ja a objekty, to proste nejde dohromady :smile12:
Proc to sakra nevezme "new Row[height](width)", kdyz bez pramateru to beha v pohode? GRRR
#include <cstdio>
#include <iostream>
class Color
{
public:
unsigned char r, g, b;
Color(unsigned char lr=0, unsigned char lg=0, unsigned char lb=0){
r = lr; g = lg; b = lb;
}
bool operator==(Color px){
if(r == px.r && g == px.g && b == px.b) return true;
return false;
}
bool operator!=(Color px){
if(r == px.r && g == px.g && b == px.b) return false;
return true;
}
};
class Row
{
public:
void allocate(unsigned int width){
px = new Color[width]();
}
void clean(){
delete [] px;
}
Color operator[](unsigned int x){
Color ret;
ret.r = px[x].r; ret.g = px[x].g; ret.b = px[x].b;
return ret;
}
Color *px;
};
class Image
{
public:
unsigned int height, width;
Image(char *filename);
~Image();
Row operator[](unsigned int y){
return row[y];
}
private:
Row *row;
};
Image::Image(char *filename){
FILE *fr;
char buffer[50];
fr = fopen(filename, "rb");
if(fr == NULL){
exit(1);
}
fread(&buffer, 1, 18, fr);
fread(&width, 1, 4, fr);
fread(&height, 1, 4, fr);
fread(&buffer, 1, 28, fr);
row = new Row[height];
for(unsigned int n=0; n<height; n++){
row[n].allocate(width);
}
for(unsigned int y=0; y<height; y++){
for(unsigned int x=0; x<width; x++){
fread(&row[y].px[x].b, 1, 1, fr);
fread(&row[y].px[x].g, 1, 1, fr);
fread(&row[y].px[x].r, 1, 1, fr);
}
fread(&buffer, 1, 2, fr);
}
fclose(fr);
}
Image::~Image(){
for(unsigned int n=0; n<height; n++){
row[n].clean();
}
delete [] row;
}
int main(){
Image img("test.bmp");
if(img[0][0] == Color(255,255,255)) std::cout << "Je to bile!!!\n";
return 0;
}
To Zelenáč :
No, možná by bylo lepší, kdybys sis o tom něco nejprve přečetl. Divíš se proč ti to nevezme new Row[xx](yy)? Na to existuje jednoduchá odpověď. Nemáš nadefinován odpovídající konstruktor. Musíš si uvědomit, že kompilátor je za tebe shopen pouze vygenerovat BEZPARAMETRICKÝ konstruktor, KOPIROVACÍ konstruktor a operátor přiřázení(ovšem ty dva poslední dělají pouze MĚLKÉ kopie!!!!, proto si je většina lidí definuje sama). Dále jsem psal cosi o referencích, nezvýrazňoval jsem to jen tak, že se mi zrovna chtělo, ale proto, že pokud chceš přiřazovat hodnoty do těch proměnných, tak z nich musíš vytvořit tzv. l-hodnoty(co to je si dohledej sám). C++ není Java nebo C#. Nicméně celá tvůj OO návrh jaksi postrádá smysl, ale nezoufej,dostat se do toho chce více času, apk už ti to ani nepříjde. Vypíchnu jen věci, které mi bijí do očí.
1) Row nemá odpovídající konstruktor
2) Proč se třída Image stará o uvolněnípoložek v Row?? Do Row přidej konstruktory, ty budou mít na starost alokaci paměti, v destruktoru třídy Row tu paměť uvolníš. Pak stačí jen v ~Image() volat delete [] row, o zbytek se postará delete a destruktor.
3) operatory [] předěle - celkem budou 2 - jeden pro čtení a druhý pro zápis
class Row
{ public:
Row()
{
}
explicit Row(size_t width)
{ // alokace
}
~Row()
{ dealokace
}
/*verze pro cteni*/
const Color& operator[](size_ ind)const
{ /*pro Debug aspon ten assert,jinak vyjimku*/
std::assert(ind < width && "spatnz index");
return px[ind];
}
/*verze pro zapis - muze stat nalevo*/
Color& operator[](size_ ind)
{ /*pro Debug aspon ten assert,jinak vyjimku*/
std::assert(ind < width && "spatnz index");
return px[ind];
}
/*dodelat kopirovaci konstruktor a operator prirazeni - pokud nechces,
aby trida sla kopirovat, tak je deklaruj jako privatni*/
}
Asi to není všechno, ale ostatní mě kdyžtak doplní.
To Jura : Ale takhle můj návrh původně vypadal.. (až na ten explicitní konstruktor - jaký má v tomto případě význam?)
Row[y](x) mi to nevezme s tohoto důvodu..
ISO C++ forbids initialization in array new
K těm ostatním poznámkám - má to pouze porovnávat barvu pixelů (což zvládá obstojně) - zápis je tu zcela zbytečný... A nechoď mi sem se znovupoužitelností :o)
Sry, pole pomocí new nelze inicializovat najednou(měl jsem asi zatmění). Takže navrhuji použít vector. Explicitní konstruktor prostě zabrání implicitnímu přetypování čísla na třídu Row. Pokud máš v plánu řádky sčítat nebo násobit a přetěžovat další operátory, tak prosím nechej to tak.
K těm ostatním poznámkám - má to pouze porovnávat barvu pixelů (což zvládá obstojně) - zápis je tu zcela zbytečný... A nechoď mi sem se znovupoužitelností :o)
Dobrá, nevím k čemu tu třídu budeš potřebovat, nicméně vracet objekt hodnotou znamená zbytečné volání kopírovacího konstruktoru. A ostaní nehodlám komentovat.
Přidej příspěvek
Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku
×Vložení zdrojáku
×Vložení obrázku
×Vložení videa
Uživatelé prohlížející si toto vlákno
Podobná vlákna
Posúvač-zmena farby — založil echo112
Zmena farby pozadia — založil Twit
Zmena farby pod kurzorom — založil dartanan
Program na dynamickú detekciu farby na ploche. — založil iridium
Program a dynamické sledovanie zmien farby. — založil iridium
Moderátoři diskuze