Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 543

/ вопрос открыт /

Здравствуйте, уважаемые эксперты! у меня такой вот вопрос: есть 2 TImage с загруженными jpeg, наложены друг на друга. как сделать так, чтобы одно изображение плавно сменялось другим и обратно, постоянно (что-то наподобие гиф-анимации). Заранее спасибо.

Phoenix Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Phoenix (статус: Посетитель)
Вопрос отправлен: 2 мая 2007, 13:03
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Матвеев Игорь Владимирович

Здравствуйте, Phoenix!
Вариант №1 - воспользоваться готовым компонентом,
реализующим данную функциональность. Полно на http://www.torry.net.

Вариант №2 - написать навый компонент самому. Нужно реализовать операцию смешивания изображений, а потом, используя эту функциональность сделать переход от одной к второй, далее к первой или к третьей картинке или вообще что угодно.
Смешивание изображений: нужны два массива (двумерных) пикселей, и не важно где они хранятся и в каком формате. Представьте себе куб, X, Y, Z - цвета Red, Green, Blue (система RGB), тогда каждый конкретный цвет - точка в объеме этого куба (значения каждого цвета - координаты). Тогда, если у Вас есть две точки в этом "цветовом" кубе, если провести между ними отрезок - это будет линия цветов смешивания, отметье на этой линии 100 точек - это будут цвета сешанного пикселя (в процентах).

См. код Приложения.

Вариант №3 - реализовать эту функциональность в модуле формы, если не требуется множественное использование. Аналогично пункту №2.

P.S. Преобразования должны проходить по таймеру.

Приложение:
  1. const
  2.  
  3.  
  4. var
  5. x, y: integer;
  6. Dest, Source1, Source2: TBitmap;
  7. pD, pS1, pS2: PByteArray;
  8.  
  9. begin
  10.  
  11. for y := 0 to Dest.Height - 1 do
  12. begin
  13. pD := Dest.ScanLine[y];
  14. pS1 := Source1.ScanLine[y];
  15. pS2 := Source2.ScanLine[y];
  16.  
  17. p^[x] := round((p1^[x] * (100 - val) + p2^[x] * val) div 100);
  18. end;
  19.  


Ответ отправил: Матвеев Игорь Владимирович (статус: Студент)
Время отправки: 2 мая 2007, 13:54

Ответ #2. Отвечает эксперт: Дима Гусаков

Здравствуйте, Phoenix!
Для того чтобы казалось, что одна картинка постепенно исчезает, а другая появляется, нужно плавно менять цвет каждой точки от начального к конечному. Удобнее и быстрее всего это делать при помощи ScanLine. Если на цвет приходится 3 байта, то легко разделить цвет точки на составляющие, значение каждой из которых должно плавно меняться от начального к конечному.

Приложение:
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3. count = 100;
  4. var
  5. i: integer;
  6. x, y: integer;
  7. bm, bm1, bm2: TBitMap;
  8. p1, p2, p: PByteArray;
  9. c: integer;
  10. k: integer;
  11. begin
  12. bm := TBitMap.Create;
  13. bm1 := TBitMap.Create;
  14. bm2 := TBitMap.Create;
  15. bm1.LoadFromFile('Bitmap1.bmp');
  16. bm2.LoadFromFile('Bitmap2.bmp');
  17. if bm1.Height < bm2.Height then begin
  18. bm.Height := bm1.Height;
  19. bm2.Height := bm1.Height;
  20. end else begin
  21. bm.Height := bm2.Height;
  22. bm1.Height := bm2.Height;
  23. end;
  24. if bm1.Width < bm2.Width then begin
  25. bm.Width := bm1.Width;
  26. bm2.Width := bm1.Width;
  27. end else begin
  28. bm.Width := bm2.Width;
  29. bm1.Width := bm2.Width;
  30. end;
  31. bm.PixelFormat := pf24bit;
  32. bm1.PixelFormat := pf24bit;
  33. bm2.PixelFormat := pf24bit;
  34.  
  35. Form1.Canvas.Draw(0, 0, bm1);
  36. for i := 1 to count - 1 do begin
  37. for y := 0 to bm.Height - 1 do begin
  38. p := bm.ScanLine[y];
  39. p1 := bm1.ScanLine[y];
  40. p2 := bm2.ScanLine[y];
  41. for x := 0 to bm.Width * 3 - 1 do
  42. p^[x] := round((p1^[x] * (count - i) + p2^[x] * i) / count);
  43. end;
  44. Form1.Canvas.Draw(0, 0, bm);
  45. Form1.Caption := IntToStr(round(i / count * 100)) + '%';
  46. Application.ProcessMessages;
  47. if Application.Terminated then break;
  48. end;
  49. Form1.Canvas.Draw(0, 0, bm2);
  50. Form1.Caption := 'done';
  51. bm1.Destroy; bm2.Destroy; bm.Destroy;
  52. end;
  53.  


Ответ отправил: Дима Гусаков (статус: 2-ой класс)
Время отправки: 2 мая 2007, 21:23


Мини-форум вопроса

Мини-форум пуст.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:39
Выполнено за 0.03 сек.