Kopiowanie fragmentu Image1 do Image1 (jpg)

0

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));

 
1

Bo ma być:

Image1.Picture.Bitmap.Canvas
0

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

0

Chyba żartujesz? Nie umiesz nawet przepisać i podstawić w dwa miejsca?

Image1.Picture.Bitmap.canvas.CopyRect(Rect(10,10,20,20),Image1.Picture.Bitmap.Canvas,Rect(30,30,40,40));
0

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?

2
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?

0
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" :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1