Czemu proste przenoszenie obszaru nie działa?
Jak to powinno być prawidłowo?
Image1.Canvas.CopyRect(Rect(10,10,20,20),Image1.Canvas,Rect(30,30,40,40));
Jeśli faktycznie ma być:
Image1.Picture.Bitmap.Canvas
to bardzo proszę do tego przykładu wstawić ten zapis
Image1.Canvas.CopyRect(Rect(10,10,20,20),Image1.Picture.Bitmap.Canvas,Rect(30,30,40,40));
i skompilować bo chyba istotny jest wynik praktyczny ????
bo oczywiście nie działa gdy obrazkiem jest format JPG
Panowie, naskoczyliście na testera_68k, że nie potrafi nawet przepisać kawałka kodu, więc ja stanę w jego obronie :)
Sprawa nie jest wcale taka oczywista. Jeżeli do Image wczytamy obrazek w formacie bmp, to nie ma znaczenia czy napiszemy Image1.Picture.Bitmap.Canvas, czy od razu Image1.Canvas. Możemy tworzyć dowolne kombinacje zapisu dla Canvas, a kod i tak zawsze wykona się poprawnie.
Problem pojawia się, gdy Image zawiera obrazek w formacie jpg. Jeżeli płótno, z którego kopiujemy zapiszemy Image1.Canvas, czyli kod będzie wyglądał np. tak
Image1.Picture.Bitmap.Canvas.CopyRect(Rect(10,10,20,20), Image1.Canvas, Rect(30,30,40,40));
to Debuger na to: Project raised exception class EInvalidOperation with message 'Can only modify an image if it contains a bitmap'.
W przypadkach jak niżej
Image1.Canvas.CopyRect(Rect(10,10,150,150), Image1.Picture.Bitmap.Canvas, Rect(40,40,180,180));
Image1.Picture.Bitmap.Canvas.CopyRect(Rect(10,10,150,150), Image1.Picture.Bitmap.Canvas, Rect(40,40,180,180));
co prawda nie otrzymamy żadnego wyjątku, ale też i program nie wykona się poprawnie. Po prostu obrazek zniknie.
Co więc teraz poradzicie autorowi wątku?
simplex napisał(a)
Co więc teraz poradzicie autorowi wątku?
Poradzimy na przyszłość od razu cały problem opisać porządnie - nie działa to bardzo szerokie i tak naprawdę nic nie mówiące pojęcie, a informacja o tym, że to jpg też pojawia się niejako przypadniem dopiero w kolejnym poście już po jego edycji... Gdyby jego opis choć odrobinę przypominał Twój, to podejrzewam, że już dawno by otrzymał odpowiedź rozwiązującą jego problem.
A zresztą tu się i tak mści programowanie "na komponentach" i nie do końca świadomość jak to działa i na czym się operuje - w taki prosty sposób się tego nie da od razu zrobić - co nie oznacza, że rozwiązania i wytłumaczenie nie da się w prosty sposób znaleźć. Na dobrą sprawę trzeba przekształcić to co jest w TImage na bitmapę i dopiero wtedy kopiować jeden kawałek w inne miejsce.
var
jpg : TJPEGImage;
begin
//warunek, ponieważ możemy do Image1 załadować zarówno bmp jak i jpg, a poniższe operacje są właściwe tylko dla jpg
//jeśli jesteś na 110% pewien, że tam jest jpg, to sprawdzanie warunku możesz pominąć
if Image1.Picture.Graphic is TJPEGImage then
begin
jpg := TJPEGImage.Create;
//odczytujemy to co jest w Image1, przekształcamy na bmp i zapisujemy z powrotem do Image1
jpg.Assign(Image1.Picture);
jpg.DIBNeeded;
Image1.Picture.Bitmap.Assign(jpg);
jpg.Free;
end;
//teraz to co zostało powyżej już napisane powinno działać
Image1.Picture.Bitmap.Canvas.CopyRect(Rect(10, 10, 20, 20), Image1.Picture.Bitmap.Canvas, Rect(30, 30, 40, 40));
PS 1. Nie wiem czy delphi potrzebuje w uses jpeg czy nie, więc ew. trzeba to tam dopisać.
PS 2. Jakiekolwiek inne rozwiązania będą zapewne tylko jakąś przeróbką powyższego - jeśli koniecznie chcesz mieć w Image1 jpg, to po wszystkim musisz dokonać jeszcze konwersji na jpg albo całą operację kopiowania wykonywać na "zewnętrznej" bitmapie i po wszystkim skonwertować ją do jpg i dodać do Image1.
PS 3. Wyjaśnienie, dlaczego w ten sposób trzeba to zrobić można znaleźć w helpie porównując sobie properties TBitmap i TJPEGImage. Po prostu TJPEGImage (czyli nasze jpg załadowane do Image1) nie ma czegoś takiego jak canvas, a więc co za tym idzie nie da się wykonać żadnych operacji na canvas'ie (w tym i nieszczęsnego CopyRect).
PS 4. Przy tak marnym opisie problemu i fatalnym, nic nie mówiącym tytule wątku "Image1 do Image1" to i tak szczęście, że wątek trafił tylko do działu Newbie, a nie od razu do kosza, więc niejako przy okazji zachęcam do lektury Jak tytułować wątki na forum? :]
simplex, czy taka odpowiedź wystarczy?
madmike napisał(a)
Poradzimy na przyszłość od razu cały problem opisać porządnie - nie działa to bardzo szerokie i tak naprawdę nic nie mówiące pojęcie...
Zgadzam się z Tobą całkowicie, ale też nie mam złudzeń, że tak jak do tej pory, będą się pojawiały tematy w stylu: "pomóżcie", czy "mam problem". Dodatkowo w opisie autor wysili się do napisania jednego zdania, co do którego czasem można mieć wątpliwości, czy jest ono w ogóle napisane po polsku. Nieraz mam nawet chęć odpowiedzieć w podobnym stylu, urywając w pół zdania, aby nie przekroczyć długości posta autora, jednocześnie informując go w postscriptum, że "jak Kuba Bogu, tak Bóg Kubie". Tyle tylko, że mi się nie chce, a wątek i tak zapewne wyląduje w koszu, co ostatnio zdarza się częściej (i bardzo dobrze).
A wracając do tematu, to oczywiście Twoja odpowiedź jest jak najbardziej wystarczająca. Stosując kod, który podałeś wystarczy nawet od razu napisać w skrócie "Image1.Canvas" i wszystko działa. Jedyny mankament takiego rozwiązania, to chwilowe mignięcie obrazka, ale pewno można sobie z tym poradzić, gdy ktoś bardzo będzie chciał.
Tak więc masz u mnie "plus" :)