ďťż

Ładny brzuch

Cześć.
Jestem troche początkujący w programowaniu więc na początku chciałem Was prosić o wyrozumiałość.
Muszę zrobic coś takiego.
Ładuję plik (obrazek) w formacie bmp. wyświetlam go komponencie Image. Z tego obrazka musze wyłuskać poszczególne piksele, stworzyś funkcję która taki piksel odpowiednio zakoduje do 1 bajta. Tu zaczyna mi się duży problem. Pliki graficzne mają różne kodowanie barw, maja przecież 1, 8, 15 24 a nawet 32 bity opisujące jeden piksel. Wiem że tego można się dowiedzieć korzystając z właściwości PixelFormat.
z funkcja kodującą do jednego bajta sobie poradzę, ale jak dostać się do poszczególnych pikseli. Czytałem że można to zrobić albo za pomocą ScanLine[] albo za pmocą Pixels[][].
Nie wiem jak tego i lub tego drugiego użyć. Nie wiem co zwracają te funkcje. Czytałem że ScanLine zwraca wskaźnik, ale nie wiem do czego, czy jest too byte czy int. I jak to wygląda przy tych kodowaniach koloru 1 lub 24 bity na piksel. Jak tego użyć.

A największą zagdaką jest dla mnie ta hierarchia. Dlaczego taki zapis:
Image1->Canvas->pixels[1][1]; daje to samo co zapis Image1->Picture->Bitmap->Canvas->Pixels[1][1]; Te wartości w nawiesie to mój przykład, to mi chodzi o to odwołanie Picture->Bitmap.

Czy możecie mi pomóc
Sławek.



Te dwa zapisy niby dają to samo, ale de'facto tym samym nie są. W pierwszym odwołujesz się bezpośrednio do płótna Image czyli zczytujesz wartość px bezpośrednio z ekranu. Przy drugim zapisie odwołujesz się do płótna ale już Bitmapy która jest w Obrazku wyświetlanym w Imagu. Niby różnica żadna, ale jak np Image będzie mniejszy niż Obrazek który wyświetla to pierwszy zapis nic Ci nie da, a drugi zwróci odpowiednie wartości prosto z obrazka :) Tak przynajmniej jest z tego co pamiętam.

A jest jakiś sposób na sprawdzenie tego, bo mi nic do głowy nie przychodzi.
A czy wiesz jak dostać sie do poszczególnych pikseli? i czym różnią się właściwości, a może metody ScanLine od Pixels

A jeszcze taka rzecz, czy można gdzieś znaleśc hierarchię tego, tzn. co pochodzi od czego lub jak są ze sobą powiązane?
Użytkownik slawek7 edytował ten post 10 czerwiec 2007, 18:13
Ogólnie to używaj bitmap, a nie canvas. pixels to jest dwuwymiarowa tablica po prostu. Poszczególne pixele są odczytywane właśnie przez nią:
pixels[x][y]. Zwracaną wartość na poszczególne kolory przerabiamy przez RGBGetRed itd (na 90% zła nazwa - przekop helpa pod kątem RGB i np. Red to znajdziesz - nie mam pod ręką więc nie sprawdzę).



ScanLine jest w teorii szybszy od Pixels. Ponieważ raz jest pobierana jedna linia z obrazka w postaci tablicy RGBQUAD. Wykorzystuje się to tak:
for(int i=0; i<bitmap->Height; ++i) { RGBQUAD* row = (RGBQUAD*)bitamp->ScanLine[i]; for(int j=0; j<bitmap->Width; ++j) { //... row[j].rgbGreen, row[j].rgbRed, row[j].rgbBlue } }
A pozatym wszystko masz w helpie. Akurat help do produktów Borlanda jest bardzo rozbudowany.

Trochę zrozumiałem.
Tylko zastanawiam sie nad tym, co w przypadku, kiedy mam plik bmp, a on ma rózne wartości bitów na piksel. Jeżeli plik bmp ma np 24 bity na piksel to wychodzi na to że jeden piksel ma 3 bajty, a jeśli bmp jest 1 bit na piksel, to co wtedy. Co zwracaja ScanLine lub Piksels. Nie mogę tego doszukać.
Nie moge też znaleść informacji, co jeśli podam w ScanLine[i] wartośc i która przekracza wysokość obrazu?

A dalej nie moge się połapac co mam stsoswać. Włśnie sprawdziłem zapis Image1->Picture->Height, daje w wyniku to samo co
Image1->Picture->Bitmap->Height. To skąd ja mam już wiedziec co się do czego odnosi. Teraz to ja juz zwarjowałem.
Pomocy w sposób łopatologiczny, a wtym helpie też ciężko coś znaleść. Jak wpiszę np RGBQUAD to nie znajduje a jak w edytorze to wpiszę najadę kursorem i nacisnę F1 to nagle jest.
Użytkownik slawek7 edytował ten post 11 czerwiec 2007, 05:59

Trochę zrozumiałem.
Tylko zastanawiam sie nad tym, co w przypadku, kiedy mam plik bmp, a on ma rózne wartości bitów na piksel. Jeżeli plik bmp ma np 24 bity na piksel to wychodzi na to że jeden piksel ma 3 bajty, a jeśli bmp jest 1 bit na piksel, to co wtedy. Co zwracaja ScanLine lub Piksels. Nie mogę tego doszukać.
Nie moge też znaleść informacji, co jeśli podam w ScanLine[i] wartośc i która przekracza wysokość obrazu?

A dalej nie moge się połapac co mam stsoswać. Włśnie sprawdziłem zapis Image1->Picture->Height, daje w wyniku to samo co
Image1->Picture->Bitmap->Height. To skąd ja mam już wiedziec co się do czego odnosi. Teraz to ja juz zwarjowałem.
Pomocy w sposób łopatologiczny, a wtym helpie też ciężko coś znaleść. Jak wpiszę np RGBQUAD to nie znajduje a jak w edytorze to wpiszę najadę kursorem i nacisnę F1 to nagle jest.

Jak masz mniej niż 24 bity, to po prostu dostajesz mniejsze wartości (przy jednym bicie czyli przy bitmapie monochromatycznej dostanie albo 1 albo 0 i dla wszystkich kolorów będzie to samo). Używaj raczej ...->picture->bitmap - jest najpewniejsze. A jak czegoś nie znajdujesz w helpie to po prostu źle szukasz skoro to tam jest ;].

A ja jednak będę nalegał z pomocą. Czy możesz mi pomóc w tym wyłuskaniu poszczególnych pikseli. I proszę zrozum że sam nie mogę sobie poradzić.

skoro masz zaldowana Bitmape to moze uzywac albo Pixels albo Scanline (ta druga metod jest szybsza bardziej w rysowaniu niz w pobieraniu, ale lepiej ja stosowac)

Pixels zwraca Ci pewno strukture, z ktorej "wyluskujesz" dane RGB, np. tak ( GetRValue( Image->Canvas->Pixels[i][j] ) - to na sam czerwony, na zielony i niebieski jest analogicznie GetG... i GetB..)

natomiast w Scanline to musisz ustalic jaka struktura bedziesz pobieral dane..
RGBQUAD sie przyda w przypadkach gdy bitmapa jest 32 bitowa (32/8 = 4)! - ja bym zastosowal 3 elementowa tablice typu unsigned char (bo przeciez wiecej jak 255 byc nie moze)

a wyluskanie konkretnego piksela wygladalo by tak:
unsigned char* P, red, green, blue; int szer, wys; P = (unsigned char*)(Image->Picture->Bitmap->ScanLine[wys]); blue = P[3*szer]; green = P[3*szer+1]; red = P[3*szer+2];

nie bede tlumaczyl dlaczego odwrotnie - to wynika z wlasciwosci bitmap (poczytaj cos o tym na necie, metoda scanline na pewno jest gdzies opisana)

PS. ostrzegam nie wszytkie bitmapy sie poprawnie wyswietlaja (mimo tego ze sa 24-bitowe, czy mniejsze) - tak juz Builder ma to do siebie..
bezpieczniej jest ladowac JPEGi
TJPEGImage *jpg = new TJPEGImage(); jpg->LoadFromFile( {FileName} ); Obrazek->Picture->Bitmap->Assign( jpg ); delete jpg;

albo przyjzec sie DIBom (czyli obrazami niezaleznymi od urzadzenia), ale tu Ci nie pomoge bo sie nigdy tym nie zjamowalem..
Użytkownik fernandez edytował ten post 11 czerwiec 2007, 11:32
Ale czy używając Pixels nie ma pewnego niebezpieczeństwa? Jeżeli okno komponentu Image ma powiedzmy 300 na 300, a załadowana bitmapa nie zajmie całego okna to czy piksels nie pokaże tego co jest puste? Bo wydaje mi się że ScanLine odwołuje się do samej bitmapy, czy tak. A co będzie jak podam za duży argument do Piksels i ScanLine?

A jak zrobić sprawdzenie. Tzn jak bym albo za pomocą ScanLine albo Pixels pobrał pokolei piksele i zrobiłbym z tego drugi obraz, czy da radę wtedy sprawdzić. Tylko jak?
Użytkownik slawek7 edytował ten post 11 czerwiec 2007, 11:08
A czy Ty czytasz co Ci się pisze? Używająć ..->picture->bitmap masz dostęp do źródła obrazu więc masz dostęp do całości niezależnie jak duży masz komponent... A jak jesteś ciekawy co się stanie jak wyjedziesz poza obraz to powiedz mi dla czego tego nie sprawdzisz sam?? Przecież komp Ci od tego nie wybuchnie!


A jak zrobić sprawdzenie. Tzn jak bym albo za pomocą ScanLine albo Pixels pobrał pokolei piksele i zrobiłbym z tego drugi obraz, czy da radę wtedy sprawdzić. Tylko jak?
I proszę pisz tak, żeby nie trzeba było się domyślać o co Ci chodzi, bo to co zacytowałem można sobie na różne sposoby interpretować...


Ale czy używając Pixels nie ma pewnego niebezpieczeństwa? Jeżeli okno komponentu Image ma powiedzmy 300 na 300, a załadowana bitmapa nie zajmie całego okna to czy piksels nie pokaże tego co jest puste? Bo wydaje mi się że ScanLine odwołuje się do samej bitmapy, czy tak. A co będzie jak podam za duży argument do Piksels i ScanLine?
jednym slowem wywali Ci wyjatek :P


A jak zrobić sprawdzenie. Tzn jak bym albo za pomocą ScanLine albo Pixels pobrał pokolei piksele i zrobiłbym z tego drugi obraz, czy da radę wtedy sprawdzić. Tylko jak?

sluchaj, to trzeba wszyzstko sobie przemyslec i odpowiednio oprogramowac..
nie wime co chcesz w ogole zrobic (chodzi o efekt koncowy)

jesli Masz Image 300x300 to on jest 300x300 (chyba ze gdzies automatycznie sie zmieniaja jego wymiary)
a jesli obrazek jest mniejszy to zawsze mozesz sprawdzic co sie wyswietli, z tego co ja pamietam to sie wyswietli biale pole obok obrazka..
Pixels pokaze wszytko to co znajduje sie w Image, a ograniczenia masz jedne (Image->Height, Image->Width)

Ja juz zwarjuję. Już nic nie wiem. Proszę powiedz mi jak jest po kolei z tymi odwołaniami.
Najpierw mamy Image1->Canvas->Pixels, czy Image1->Picture->Bitmap->Canvas->Pixels. Już nie wiem co się do czego odwołuje? Ja zdaje sobie sprawę że jest to banalne, ale już tak mi się namieszło, że już nic nie wiem. Co fizycznie oznacza Canvas, a co Bitmap, dzo czego mam się kiedy odwoływać i co ma być z przodu.

bezposrednio pixele mozesz pobierac TYLKO z TImage->Canvas, a wiec Image->Canvas->Pixels

Image->Picture->Bitmap juz jest innym typem (Graphics::TBitmap) i do niego mozesz sie odwolywac Scanline'em

fizycznie jest to ten sam strumien danych, czyli np. cokolwiek zrobisz za pomoc Pixelsa, bedziesz mogl to odczytac z Bitmapy i na odwrot (takie banalne tlumaczenie, ale o tym ze to jest to samo to powinnien Ci mowic wskaznik Image)
Użytkownik fernandez edytował ten post 11 czerwiec 2007, 21:09
Zmieszął mnie taki fragment z sieci:
for (int i=0; i<=Image1->Height-1; i++) for (int j=0; j<=Image1->Width-1; j++) { TColor Kolor = Image1->Picture->Bitmap->Canvas->Pixels[j][i]; byte r,g,b; r = 0; g = 0; b = GetBValue(Kolor); Image1->Picture->Bitmap->Canvas->Pixels[j][i] = RGB(r,g, B); }

Według opisu Usuwanie z obrazka kolorów czerwonych, zielonych i niebieskich

Albo to do tworzenia negatywu

for (int i=0; i<=Image1->Height-1; i++)
for (int j=0; j<=Image1->Width-1; j++)
{
TColor Kolor = Image1->Picture->Bitmap->Canvas->Pixels[j][i];
byte r,g,b;
r = 255 - GetRValue(Kolor);
g = 255 - GetGValue(Kolor);
b = 255 - GetBValue(Kolor);
Image1->Picture->Bitmap->Canvas->Pixels[j][i] = RGB(r,g, B);
}

Zamiast buźki pownoo być b
Użytkownik slawek7 edytował ten post 11 czerwiec 2007, 14:05
no i co w tym dziwnego, bo ja nie wiem ??

jedyne co moze dziwic to ten pierwszy kod - bo sluzy on do usuwania kanalu czerwonego i zielonego a niebieski pozostawai bez zmian, a nie tak jak napisales..
Użytkownik fernandez edytował ten post 11 czerwiec 2007, 18:18

bezposrednio pixele mozesz pobierac TYLKO z TImage, a wiec Image->Canvas->Pixels

Image->Picture->Bitmap juz jest innym typem (Graphics::TBitmap) i do niego mozesz sie odwolywac Scanline'em

WTF?? Od kiedy to nie można bawić się pixels na bitmapie? Czy ja o czymś nie wiem? Chyba że C jest tak pokręcone że w BCB nie działają takie rzeczy jak w Delphi... Może w bcb nie istnieje bitmap->canvas?


WTF?? Od kiedy to nie można bawić się pixels na bitmapie? Czy ja o czymś nie wiem? Chyba że C jest tak pokręcone że w BCB nie działają takie rzeczy jak w Delphi... Może w bcb nie istnieje bitmap->canvas?
a istnieje..
rozpedzilem sie, po prostu od kiedy znam metode Scanline w ogole Pixelsa nie uzywam..
z kazdego obiektu, ktory ma Canvas mozna sie odwolac Pixelsem ( Scanlinem juz z Canvas nie odczytasz )

mozna rzec, ze Image->Canvas i Image->Picture->Bitmap->Canvas to "praktycznie" to samo..

PS. Borland Delphi i Borland C++ to to samo - roznia sie tylko jezykiem programowania (moze czyms jeszcze ale to pewno jakies szczegoly)
Użytkownik fernandez edytował ten post 11 czerwiec 2007, 21:09

a istnieje..
rozpedzilem sie, po prostu od kiedy znam metode Scanline w ogole Pixelsa nie uzywam..
z kazdego obiektu, ktory ma Canvas mozna sie odwolac Pixelsem ( Scanlinem juz z Canvas nie odczytasz )

mozna rzec, ze Image->Canvas i Image->Picture->Bitmap->Canvas to "praktycznie" to samo..

PS. Borland Delphi i Borland C++ to to samo - roznia sie tylko jezykiem programowania (moze czyms jeszcze ale to pewno jakies szczegoly)

No właśnie nie to samo - różnica jest duża. image->Canvas jest płutnem komponentu na które jest nanoszone to co jest w picture->bitmap. Do półki image i bitmap mają identyczne rozmiary to różnica jest nieodczuwalna, ale jak rozmiary się różnią, to już widać ową różnice.

Tak samo uważałem, ale mnie tym pixels'em wybiłeś :P.

No właśnie. DZięki Tobie zaczynam to rozumieć. A czy możesz mi przybliżyć poszczególne obiekty. Bo ja to tak rozumiem. Image jest to kontrolka odpowiedzialna za obraz, Image->Canvas jest to to co widać na ekranie, czy tak. A Image->Picture oraz Image->Bitmap. Co to jest?

Właśnie sprawdziłem taką rzezcz. Umieśiłem komponent Image nadałem wymiary 300 na 300, ustawiłem AutoSize na False, załadowałem obrazek i stworzyłem coś takiego w zdarzeniu OoMouseMove:

TColor Kolor = Image1->Picture->Bitmap->Canvas->Pixels[X][Y];
byte r,g,b;
r = 255 - GetRValue(Kolor);
g = 255 - GetGValue(Kolor);
b = 255 - GetBValue(Kolor);

Teraz każdą R, g i b wyświetlam w postaci liczby w polu Edit. I co ciekawego dla mnie. Jeżeli obraz nie zajmuje całej wielkości obiektu Image ( a taki specjalnie wybrałem) to wartości w polach Edit powinny się zmieniac tylko w czasie ruchu myszka ale tylko po najechaniu na obraz. A tu mienia sie na całym obiekcie Image. Po prostu działa tak samo jak napiszę TColor Kolor = Image1->Canvas->Pixels[X][Y];

I tego nie rozumiem. Bo jeśli Bitmap->Canvas odwołuje się do obrazka to dlaczego odwołuje się do całości Image. Bo tak jak napisał Ali240 to by mi sie zgadzało, a teraz się nie zgadza? Możesz mi to wyjaśnić.
Użytkownik slawek7 edytował ten post 12 czerwiec 2007, 06:02

No właśnie nie to samo - różnica jest duża. image->Canvas jest płutnem komponentu na które jest nanoszone to co jest w picture->bitmap. Do półki image i bitmap mają identyczne rozmiary to różnica jest nieodczuwalna, ale jak rozmiary się różnią, to już widać ową różnice.
tyle ze domyslnie maja ten sam rozmiar, a jak widzimi kolega nic nie zmienia w ustawieniach samej Bitmapy...

Czemu symetrycznie kolory?
Jeżeli chcesz testować to połóż drugi image obok, ustaw mu rozmiary image->picture->bitmap na rozmiary image i kopiuj pojedyńcze pixele z pierwszego image przy ruszaniu myszką :).

NApisałem postą funkcję kopującą obraz do drugiego komponentu image Image.
Image1 jest po lewej stronie, a image2 po prawej. Image1 ma wymiary ustawione na 300x300 natomiast Image2 400x400.
Image1 ma ustawione Proportional na True, AutoSize na False. To co pokazuje się w okienku Edit na dole to szerokości Bitmapy i samego Image (w kodzie szczegóły).
Ale dlaczego obraz kopije się tak jak widać na obrazku?
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { if (OpenPictureDialog1->Execute()){ Edit1->Text = OpenPictureDialog1->FileName; Image1->Picture->LoadFromFile(OpenPictureDialog1->FileName); } else{ Edit1->Text = ""; exit; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { Edit2->Text=Image1->Picture->Bitmap->Width; Edit3->Text=Image1->Width; for(int y = 0; y < Image1->Picture->Bitmap->Height; y++) { for(int x = 0; x < Image1->Picture->Bitmap->Width; x++) { Image2/*->Picture->Bitmap*/->Canvas->Pixels[x][y]= Image1->Picture->Bitmap->Canvas->Pixels[x][y]; } } Image2->Refresh(); } //---------------------------------------------------------------------------

O nie mogę umieścić zdjęcia więc podaje link Zrzut programu

Dlaczego po kopiowaniu widac tylko część?

Bo kopiujesz z img->picture->bitmap czyli z oryginału. W image1 masz włączone zmniejszanie obrazu (stretch zdaje się) więc na nim widać obraz dopasowany do rozmiaru komponentu. Tutaj ładnie widać różnice między img->canvas gdzie jest to co widzimy na ekranie a img->picture->bitmap->canvas gdzie jest źródło z którego korzysta komponent :).

Strech jest na false. żadne inne zmiany nie pomagają. Też o tym pomyślałem ale to nie to. A nawet jak zmieniłem trochę kod i wpisałem
Image2->Picture->Bitmap->Canvas->Pixels[x][y]= Image1->Canvas->Pixels[x][y];

To niby powinien skopiować to co widać a jest to samo, co poprzednio


Strech jest na false. żadne inne zmiany nie pomagają. Też o tym pomyślałem ale to nie to. A nawet jak zmieniłem trochę kod i wpisałem
Image2->Picture->Bitmap->Canvas->Pixels[x][y]= Image1->Canvas->Pixels[x][y];

To niby powinien skopiować to co widać a jest to samo, co poprzednio

A jakie wymiary oryginalne ma obrazek?
// Skoro obrazek ma szerokość 800 a widać go w całości na 300 px to chyba logiczne, że musiał zostać przeskalowany, co nie?
Użytkownik Ali240 edytował ten post 13 czerwiec 2007, 11:06
Zgadza się. Nie zauważyłem tego. Ale dopiero się uczę, więc proszę o wyrozumiałośc.

A mam w takim razie jeczsze taka sprawę.
Jeżei mam obraz powiedzmy 300x300pikseli, czy jest jakaś możliwośc zrobienia z niego 100x100, ale albo
1. tak abym mógł ustawić że potrzebny mi jest określony fragment
2. albo tak że cały abraz zmniejszam do 100x100 pikseli pogarszcając rozdzielczość.

Kai prosty program graficzny

Sprawdź funkcje canvasa:
StretchDraw oraz CopyRect

Patrzyłąem na te funkcję i muszę przyznać że sam sobie nie poradzę. Dałbyś radę pomóc?


Patrzyłąem na te funkcję i muszę przyznać że sam sobie nie poradzę. Dałbyś radę pomóc?
Niestety nie mam zamiaru. Funkcje są proste, wystarczy się wczytać w samego helpa i będzie wszystko jasne. Poza tym - jest maaaaasa przykładów w necie (zapewne w demos też co nieco by się znalazło)... Pewnie samo przeszukanie forum też by wszystko wyjaśniło. Także trochę samodzielności...

Zapytam jeszcze o kilka rzezcy.
1. CZy to wszystko będzie działać na obrazach czarnobiaych?
2. CZym różni sie TColor od TColorRef
4. Czym różni sie RBGQUAD od RGBTRIPLE (oprócz nazwy) cfodzi mi o użycie. Niestety w helpie jest tylko opis sruktury co zawiera.

I które z tych działają na obrazach kolorowych a które z czarnobiałych?

Czy to jest tak że jeśli używam Pixels[] to w zależności od PixelFormat mam rózne rzeczy. Mam na mysli to ze dla 24 bitów mogę dostać jako TColor wartości R, G, B. Ale jak to się ma do obrazów 1 bit na piksel? Nie rozumiem


Zapytam jeszcze o kilka rzezcy.
1. CZy to wszystko będzie działać na obrazach czarnobiaych?
2. CZym różni sie TColor od TColorRef
4. Czym różni sie RBGQUAD od RGBTRIPLE (oprócz nazwy) cfodzi mi o użycie. Niestety w helpie jest tylko opis sruktury co zawiera.
I które z tych działają na obrazach kolorowych a które z czarnobiałych?

Czy to jest tak że jeśli używam Pixels[] to w zależności od PixelFormat mam rózne rzeczy. Mam na mysli to ze dla 24 bitów mogę dostać jako TColor wartości R, G, B. Ale jak to się ma do obrazów 1 bit na piksel? Nie rozumiem

Zdaje się że dostaniesz zawsze kolor RGB (nie wiem co się dzieje w przypadku 32 bitów - to poza moim dozwolonym poziomem abstrakcji, chyba że, trzeba ręcznie to dekodować - fuj ;)). Po prostu np. przy bitmapie monochromatycznej dostaniesz albo same 0 albo same 255.
1. A czemu nie?
2,4(a 3 gdzie? :D). Różni się tym co jest pokazane w helpie. Skoro inna budowa to pewnie używa się przy innych funkcjach...

4.
RGBQUAD - 4 bajty na pixel (zastosowanie - bitmapy 32-bit), dodatkowy kanal raczej nie uzywany w bitmapach
RGBTIRPLE - 3 bajty na pixel (zastosowanie - bitmapy 24-bit)

Dziękuję.
Nie wiem czy tego nie doczytałem, ale tam nie było nic o tym napisane że te do 24 (32)bity. Poza tym jesli to tylko do takich wartości to co mapami 1biowymi i ScanLine, trochę to nie uniwersalne bo muszę z góry wiedzieć ile bitów na piksel, czyli zawsze czytać PixelFormat?

Ale czy to samo jest z Pixels[], bo wydaje mi się ze jednak jest to prostrze w takim razie.
Tu niby zawsze zwraca strukturę TColor, czy tak? Ale co dostaję przy skarjnych wartościach tzn. dla map 1 bitowych i 32 bitowych na piksel?

Nie rozumiem tego. Naisałem w pętli (podwójne for) taką instrukcję: Image2->Canvas->Pixels[x][y] = clRed;
Ale nic mi się nie pokazuje. Bo na początku to chciałem taką myśl stworzyć: Image2->Canvas->Pixels[x][y] = (TColor)RGB(r,g,B); ale też nie zadziałało.

A czym sie to różni: TColor od TColorRef?

Nic nie dało bo zapewne komponent odświeżył widok i przemalował źródło od nowa. Więc może jednak zastosuj się do tego co było napisane i maluj po źródle...

A jak by zrealizować samo rysowanie po Image?
Przecież to powinno działać? A dlaczego tu nagle nie ma śladu?


A jak by zrealizować samo rysowanie po Image?
Przecież to powinno działać? A dlaczego tu nagle nie ma śladu?

Powiedz którego słowa nie zrozumiałeś. Czy odświeżył widok jest niezrozumiałe czy może coś innego?
...
Użytkownik Ali240 edytował ten post 14 czerwiec 2007, 19:16
Słuchaj jak nie chcesz odpisywać to poprostu sobie daruj.
CZy nie rozumiesz że wywołanie prostej "książkowej" funkcji rusowania nie przynosi efektu. Już nie wspominam o tym że błędy ortograficzne robisz, bo co innego jest niestosowanie znaków polskich, a co innego pisanie "rz" w miejsce "ż".
Zaczynam widzieć że to forum robi się typu ja wiem, ale nie powiem bo Twój tekst że mi się niechce odpowiadać wczoraj był chyba trochę kiepskim żartem. Po prostu nie odpowiadaj, jak nie masz ochoty.

Siemka.


Słuchaj jak nie chcesz odpisywać to poprostu sobie daruj.
CZy nie rozumiesz że wywołanie prostej "książkowej" funkcji rusowania nie przynosi efektu. Już nie wspominam o tym że błędy ortograficzne robisz, bo co innego jest niestosowanie znaków polskich, a co innego pisanie "rz" w miejsce "ż".
Zaczynam widzieć że to forum robi się typu ja wiem, ale nie powiem bo Twój tekst że mi się niechce odpowiadać wczoraj był chyba trochę kiepskim żartem. Po prostu nie odpowiadaj, jak nie masz ochoty.

Siemka.

Tu nie jest kwestia czy chcę czy nie, tylko raczej kwestia tego czy Ty w ogóle czytasz to co Ci się pisze czy nie. Napisałem Ci powód, dla którego nie widać efektu rysowania po canvasie image'a a Ty dalej uparcie pytasz czemu nie działa. Forum nie jest miejscem gdzie każdy będzie dawał rozwiązania - to się mija z celem, skoro wszystko można znaleźć w helpie/na forum/w demach/w google. Więc jak ktoś daje podpowiedzi to przewałkuj temat zanim coś napiszesz. Rozumiem, że można nie wiedzieć jak do czegoś podejść, ale do *** jak ktoś daje nazwę funkcji to bądź tak miły i zerknij za przykładami, a nie zawracasz tyłek w sprawach, na które można znaleźć odp. wpisując w google to co Ci podano + 'example'/'przykład'!
Uszanuj to, że ktoś Ci się stara pomóc, że wykorzystuje na to czas który mógłby wykorzystać na pracę...

[OT]Dzięki za znalezienie błędu - poprawiony. Jednak ugryź się trochę w język (palce?) zamiast robić wielkie halo - na ten topik zdaje się, że był to mój pierwszy ort, natomiast Twoich jest dużo więcej (w samym poście krytykującym mnie masz 2 orty + 1 caps). A co do niestosowania polskich znaków - od kilku tygodni przystosowuję się do używania ogonków bo polubiłem UTF (;)) i jakoś nie wydaje mi się, żebym je omijał w tym topicu.[/OT]

// @Down: Czytaj uważnie - nie pisałem żeby coś odświeżać, tylko że prawdopodobnie gdy się po canvasie image'a maluje to komponent się odświeża i kopiuje źródło, więc nie widać co się namalowało.
Użytkownik Ali240 edytował ten post 14 czerwiec 2007, 22:19
o ludzie <_<

nic nie trzeba odswiezac (w przypadku tak prostych programow), odwolujesz sie bezposrednio do Pixela i zmieniasz go od razu w locie - tym samym Image sie zmienia automatycznie po zmianie Pixela..

pytanie gdzie umiesciles kod rysujacy, bo moze o to wlasnie chodzi..

Przepraszam, bo faktycznie mnie trochę poniosło, i ugryzłem się. Ok przyznaję się do błędu.
Ale proszę Cię o troche wyrozumiałości. Nad taką głupia rzeczą siedzę kombinuję, sprawdzam wszystko jak jest podane w Helpie, przeglądam książki, i powinno działać, a tu nawet kropak się nie pojawia.

To rysowanie umieściłem w obsłudze
void __fastcall TForm1::Button3Click(TObject *Sender)
{
for(x = 0; x < Image1->Picture->Bitmap->Width; x++)
for(y = 0; y < Image1->Picture->Bitmap->Height; y++)
Image2->Canvas->Pixels[x][y] = clRed;

}

To jest typowy opis z książki, ale tu nie działa. Wysokość i szerokość komponentu Image2 mam ustawioną na 400x400

---------------------
Jeszcze coś zrobiłem bo myślałem że może to zadziała, ale też niedziała:
void __fastcall TForm1::Button3Click(TObject *Sender)
{

Graphics::TBitmap *bmp = new Graphics::TBitmap;
int x,y;

for(x=0; x<100;/*Image2->Width;*/ x++)
for(y=0; y<100;/*Image2->Height;*/ y++)
bmp->Canvas->Pixels[x][y] = clRed;

Image2->Picture->Assign(bmp);
Image2->Show();
delete bmp;

}
Użytkownik slawek7 edytował ten post 15 czerwiec 2007, 05:56

Jeszcze coś zrobiłem bo myślałem że może to zadziała, ale też niedziała:
void __fastcall TForm1::Button3Click(TObject *Sender)
{

Graphics::TBitmap *bmp = new Graphics::TBitmap;
int x,y;

for(x=0; x<100;/*Image2->Width;*/ x++)
for(y=0; y<100;/*Image2->Height;*/ y++)
bmp->Canvas->Pixels[x][y] = clRed;
Image2->Picture->Assign(bmp);
Image2->Show();
delete bmp;
}

Jak na moje oko to powinieneś jeszcze przed zaczęciem rysować ustawić rozmiary bmp bo standardowo ma 1x1 (lub 0x0?). A czemu nie spróbujesz tak (nie programuje w C++ więc może być parę błędów, ale chodzi głównie o idee):
void __fastcall TForm1::Button3Click(TObject *Sender) { int x,y; // Jeżeli nic nie masz załadowane do image2 to daj te 2 linie: { Image2->Picture->Bitmap->Width = 100; Image2->Picture->Bitmap->Height = 100; // } for(x=0; x<Image2->Picture->Bitmap->Width; x++) { for(y=0; y<Image2->Picture->Bitmap->Height; y++) { Image2->Picture->Bitmap->Canvas->Pixels[x][y] = clRed; }; }; // Poniższe jakby się samo nie odświeżało: Image2.Refresh(); }

P.S. Pamiętaj o codebox - ułatwia czytanie forum

// Edit:

To rysowanie umieściłem w obsłudze
void __fastcall TForm1::Button3Click(TObject *Sender)
{
for(x = 0; x < Image1->Picture->Bitmap->Width; x++)
for(y = 0; y < Image1->Picture->Bitmap->Height; y++)
Image2->Canvas->Pixels[x][y] = clRed;

}

To jest typowy opis z książki, ale tu nie działa. Wysokość i szerokość komponentu Image2 mam ustawioną na 400x400

Na delphi u mnie po canvie da się malować :). A załadowałeś tam obrazek? Bo malowanie bezpośrednio po sobie u mnie przyjmuje tak jak malowanie po źródle - rozmiar ograniczony do rozmiaru ustawionego w image->picture->bitmap. Więc możliwe, że tu leży problem bo nie widze u Ciebie zmieniania rozmiarów...
Użytkownik Ali240 edytował ten post 15 czerwiec 2007, 08:34
Zrobiłem jak napisałeś. Nie działa:-(

No juz nie mam pojęcia o co chodzi. Czy to zawsze z najprostrzymi rzeczami musi być taki problem.
Sobie nawet nie wyobrażasz jaki wściekły na to jestem.
Masz może jeszcze jakiś pomysł?

Daj cały kod na pastebina jakiegoś (z kolorowaniem składni, np. http://pastebin.ca/) i wrzuć exe gdzieś.
// Może ktoś kto posiada BCB zweryfikować czy tamten kod działa?
Użytkownik Ali240 edytował ten post 15 czerwiec 2007, 10:55

void __fastcall TForm1::Button3Click(TObject *Sender)
{
for(x = 0; x < Image1->Picture->Bitmap->Width; x++)
for(y = 0; y < Image1->Picture->Bitmap->Height; y++)
Image2->Canvas->Pixels[x][y] = clRed;

}


czemu nie zrobisz tak?
for(int x = 0; x < Image1->Width; x++) for(int y = 0; y < Image1->Height; y++) Image1->Canvas->Pixels[x][y] = clRed;

male modyfikacje kodu Ali240:
Image1->Picture->Bitmap->Width = Image1->Width; //konieczne Image1->Picture->Bitmap->Height = Image1->Height; //to tez for(int x=0; x<Image1->Picture->Bitmap->Width; x++) for(int y=0; y<Image1->Picture->Bitmap->Height; y++) Image1->Picture->Bitmap->Canvas->Pixels[x][y] = clRed;

chodzi wlasciwie o to samo i u mnie dziala
jesli u Ciebie nie dziala to BCB masz zrypane - z reszta nie zdziwiloby mnie to, to jest beznadziejny program pod wzgeldem stabilnosci :/

edit@DOWN:
chodzi o to ze, ze BCB sie sam "wysypuje" (np. sypie bledami, ktorych nie powinno byc) - trzeba go restartowac, zeby dzialal poprawnie (a czasem i to nie pomaga)
Użytkownik fernandez edytował ten post 17 czerwiec 2007, 14:05
I faktycznie tu był problem. bie była ustawiona wielkośc obszaru. A o co chodzi z tą stabilnością?

Czy istnieje taka możliwość ze jeśli mam do image1 załadowany jakiś oraz to do image2 chcę tylko jakąś część z pierwszego. Cała rzecz polega na tym że potrzebne jest mi tu zmniejszenie wielkości obrazu. A dodatkowo jeszcze kadrowanie. Czy jest taka możliwość aby wykadrować sobie myszką poprzez przesuwanie po źródle wielkością karu?

jest, zobacz przyklad jakiegos programu typu paint - tak samo jak tam sie rysuje prostokat, tak samo tu rysujesz wielkosc kadru. pozniej pobierasz te wielkosci, i kopiujesz ta czesc bitmapy, wklejasz do docelowej.


I faktycznie tu był problem. bie była ustawiona wielkośc obszaru. A o co chodzi z tą stabilnością?

Czy istnieje taka możliwość ze jeśli mam do image1 załadowany jakiś oraz to do image2 chcę tylko jakąś część z pierwszego. Cała rzecz polega na tym że potrzebne jest mi tu zmniejszenie wielkości obrazu. A dodatkowo jeszcze kadrowanie. Czy jest taka możliwość aby wykadrować sobie myszką poprzez przesuwanie po źródle wielkością karu?


metody onmouseup i onmousedown:
pobierasz x, y - wyznaczasz obszar,
a jak przerysowac z image do image to juz wiesz..

PS. sproboj napisac to zrobic Pixelsem i Scanlinem to zobaczysz roznice..
Użytkownik fernandez edytował ten post 17 czerwiec 2007, 14:10
Dzięki.
Trochę nie tak. Tu chodzi o to że wymiary tego kadru muszą być ustalone (ma byc 96 na 67 pikseli). Natomiast porusząć ma się ten prostokąt który ma służyć do kadrowania. Tak opisowo to ma to działać tak: ustalony prostkokąt przesuwa się po obrazku i to co jest w zasięgu tego prostokąta zostaje przekopiowane do oddzielnego komponentu Image.

A na czym polega zmiana wymarów obrazu? Jeśli bitmapa ma 300x300 pikseli to na czym polega zrobienie z niej bitmapy np 100x100. Bo nie wiem czy jest to pozbycie się co któregoś piksela, czy wyciągnięcie np średniej z kilku po sobie następujących?

A faktycznie ostatnio coś mi się zaczęło z BCB dziać dziwnego. Niby działa ale po zamknięciu programu wywala mi komunikat typu: An exception (C0000005) occurred during DllEntryPoint or DllMain in module \\ideffilters60.bpl"
Ja klikam na ok w tym komunikacie to zaczyna to znowu się pojawiać. Muszę wymisić mu zamknięcie procesu. Czy tesz tak masz i skąd to się bierze. Wcześniej tego nie miałem nigdy.
Użytkownik slawek7 edytował ten post 17 czerwiec 2007, 15:44
to ja bym na Towim miejscu zrobil jakiegos przezroczystego Shape'a (to chyba gdzies w opcjach Brush sie robi) i jego (oraz Image) umiescil w Panelu, zeby bylo mniej problemow z obliczaniem wspolrzednych
nastepnie sprawdzal gdzie sie znajduje owy Shape i za pomoca jego wymiarow odczytywal dane z Image

co do zminay wielkosci Image musialbys to sam sprawdzic, nigdy nie probowalem (nie bylo mi to potrzebne) i nie wiem czym to grozi
najlepiej wczytac jakis obraze ki po kliknieciu zmeinic jego wymiary i obserwowac co sie stanie..

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • zsf.htw.pl
  •