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

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

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

Delphi.int.ru Expert

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

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

#   

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


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

Подробнее »



Вопрос # 2 377

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

Здравствуйте, уважаемые эксперты!
Есть база на fdb есть таблица дапустим сотрудники, етсь поле grafic имеет BLOB на форме DBGrid DBImage все хорошо заносится и выводится (изображение), и я тут столкнулся с небольшой проблемой мне нужно изображение которое в DBImage переворачивать по 90 градусов (при нажатие на кнопку) как этого добиться?

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

Вопрос задал: Danswin (статус: Посетитель)
Вопрос отправлен: 2 февраля 2009, 07:41
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Пупкин В.В.

Здравствуйте, Danswin!
например так:
procedure TForm1.Button2Click(Sender: TObject);
var bmp:tbitmap;
i,j:integer;

begin
bmp:=tbitmap.Create;
bmp.Height:=DBImage1.Picture.Bitmap.Width;
bmp.Width:=DBImage1.Picture.Bitmap.Height;

for i:=0 to DBImage1.Picture.Bitmap.Height-1 do
for j:=0 to DBImage1.Picture.Bitmap.Width-1 do
bmp.Canvas.Pixels[i,j]:=DBImage1.Picture.Bitmap.Canvas.Pixels[j,i];

DBImage1.Picture.Assign(bmp);
bmp.Free;
end;
но метод оч медленный
можно ускорить, но там свои подводные камни =(
в целом это направление

Ответ отправил: Пупкин В.В. (статус: 1-ый класс)
Время отправки: 4 февраля 2009, 12:01


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

Всего сообщений: 18; последнее сообщение — 13 февраля 2009, 19:38; участников в обсуждении: 3.
Danswin

Danswin (статус: Посетитель), 4 февраля 2009, 16:47 [#1]:

В целом не плохо даже очнеь хорошо, )))) только куда копать чтоб облегчить переварот)) а то он ваше так задумывается) и притом очень на долго))
Вадим К

Вадим К (статус: Академик), 4 февраля 2009, 17:09 [#2]:

через доступ к пикселям разворот... да... это тяжелый путь. В данном случае более быстрым методом будет с помощью ScanLine считать в массив точки, а потом вторым приходом залить назад в правильном порядке. Почему нельзя сразу? просто ScanLine позволяет работать быстро, если если мы перебираем точки в строке. Мало того, если всё очень аккуратно сделать, то одно копирование можно сделать очень быстрым, так как можно копировать целыми строками.
Галочка "подтверждения прочтения" - вселенское зло.
Danswin

Danswin (статус: Посетитель), 4 февраля 2009, 17:46 [#3]:

Вадим, если вас не затруднит, моглибы вы хотябы ) немножечко продемонстрировать код) а то уж мне эти масивы точно не как не сделать (токо начинаю и то в БД работать) а тут масимы и перебор, ))))
еслив ас не затруднит?
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 4 февраля 2009, 17:50 [#4]:

про это я и говорил ScanLine дает результат в 300 раз быстрее
но код не так то прост ) как на первый взгляд кажется
Вадим К

Вадим К (статус: Академик), 4 февраля 2009, 18:14 [#5]:

ну 300 - это с потолка цифра, но в некоторых случаях прирост просто поражает.
По поводу кода... увидим, может напишу...
Галочка "подтверждения прочтения" - вселенское зло.
Danswin

Danswin (статус: Посетитель), 4 февраля 2009, 18:17 [#6]:

Вадим, прошу можно код)))) верю что такой сложный, может на сот вам положу за вознограждения))) как спасибо)
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 4 февраля 2009, 18:25 [#7]:

нет не с потолка
1024*1024px
разница во времени в 300 быстрее
Вадим К

Вадим К (статус: Академик), 4 февраля 2009, 18:28 [#8]:

Поверьте, код там не такой и сложный. пара циклов всего.
Галочка "подтверждения прочтения" - вселенское зло.
Danswin

Danswin (статус: Посетитель), 4 февраля 2009, 18:31 [#9]:

Для олвото пару циклов ппс как много))) а для грамотного специалиста это раз плюнуть)
а еще кроме этого етсь еще методу разварачвать, вот в винде есть программа просмоторщик разве это по это принцепу утсроено? думаю что нет и разворачивает довольно быстро.
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 4 февраля 2009, 18:35 [#10]:

ну если пару дык написалиб
при нормальной скорости печати на это уйдет 2 мин
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 4 февраля 2009, 18:36 [#11]:

если не получится завтра сделаю
бб
Danswin

Danswin (статус: Посетитель), 4 февраля 2009, 18:36 [#12]:

)))))
Ну так написал будем ждать) значит не пару ))
Вадим К

Вадим К (статус: Академик), 4 февраля 2009, 18:40 [#13]:

И почему мы все так любим делать быстро выводы,Пупкин В.В.
Особенно, если у тебя под рукой нет делфи, и ты не под виндовсом...
Написать то идею я могу. но что оно скомпилиться сразу... и потом точно заработает. могу какую то мелочь упустить, и оно не будет работать как надо.
Галочка "подтверждения прочтения" - вселенское зло.
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 5 февраля 2009, 18:31 [#14]:

что никак? =)
не так то просто со ScanLine

дело в том что тут не пару циклов, а нужно писать свой код под каждый формат bmp, хотя он не сильно отличается

вот самый простой пример для bmp у которого 8 бит на пиксель

procedure TForm1.Button3Click(Sender: TObject);//быстрее

var bmp:tbitmap;
i,j:integer;
p:pByteArray;
p_bmp:array of pByteArray;

begin
if DBImage1.Picture.Bitmap.PixelFormat<>pf8bit then
begin
application.MessageBox('Надо 8 бит на пиксель','Внимание');
exit;
end;


bmp:=tbitmap.Create;
bmp.Height:=DBImage1.Picture.Bitmap.Width;
bmp.Width:=DBImage1.Picture.Bitmap.Height;
bmp.PixelFormat:=DBImage1.Picture.Bitmap.PixelFormat;
bmp.HandleType:=DBImage1.Picture.Bitmap.HandleType;
bmp.Palette:=DBImage1.Picture.Bitmap.Palette;

setlength(p_bmp,bmp.Height);
for i:=0 to bmp.Height-1 do
begin
p_bmp[i]:=bmp.ScanLine[i];
end;

for i:=0 to DBImage1.Picture.Bitmap.Height-1 do
begin
p:=DBImage1.Picture.Bitmap.ScanLine[i];
for j:=0 to DBImage1.Picture.Bitmap.Width-1 do
p_bmp[j,i]:=p[j];
end;


DBImage1.Picture.Bitmap.Assign(bmp);

bmp.FreeImage;
FreeAndNil(bmp);


end;

придирки к коду не принимаются, надо было предлогать свой (эт к кандидатам)
замечено выпадание цветов при повторном повороте, короч доработаете сами чет лениво, да с кандачка не решается.

по поводу других форматов все тож самое только учитывать размерность т.к. если например 24 бита то надо их и считывать > TRGBTriple
Danswin

Danswin (статус: Посетитель), 6 февраля 2009, 16:16 [#15]:

Пупкин В.В.
Добрый день, еслив ам не трудно то сделайте полной код, а то с 8 битым тож работает а у меня фотографии тоетсь нужно до писывать а техноологию этого ненаю
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 9 февраля 2009, 14:45 [#16]:

чтоб цвета не выпадали при повторном нажатии на кнопку после
DBImage1.Picture.Bitmap.Assign(bmp);
надо
DBImage1.Picture.Bitmap.FreeImage;

=)
Пупкин В.В.

Пупкин В.В. (статус: 1-ый класс), 13 февраля 2009, 18:06 [#17]:

нашел почему по кругу не крутится (как вы просили)
просто получается зеркальное отображение с поворотом
чтоб это исправить нужно в варианте попиксельной долгой обработки заменить bmp.Canvas.Pixels[i,j]:=DBImage1.Picture.Bitmap.Canvas.Pixels[j,i];

на bmp.Canvas.Pixels[i,j]:=DBImage1.Picture.Bitmap.Canvas.Pixels[DBImage1.Picture.Bitmap.Width-j,i];

делайте соответствующие выводы для быстрого варианта! =)
Danswin

Danswin (статус: Посетитель), 13 февраля 2009, 19:38 [#18]:

Круто получилось, только не получилось сделать для быстрого переварота , если честно я там запутался с
for i:=0 to DBImage1.Picture.Bitmap.Height-1 do
for j:=0 to DBImage1.Picture.Bitmap.Width-1 do
bmp.Canvas.Pixels[i,j]:=DBImage1.Picture.Bitmap.Canvas.Pixels[DBImage1.Picture.Bitmap.Width-j,i];
чтобы переобразить в
bmp.Height:=DBImage1.Picture.Bitmap.Width;
bmp.Width:=DBImage1.Picture.Bitmap.Height;
bmp.PixelFormat:=DBImage1.Picture.Bitmap.PixelFormat;
bmp.HandleType:=DBImage1.Picture.Bitmap.HandleType;
bmp.Palette:=DBImage1.Picture.Bitmap.Palette;

Короче я путаюсь сделать преобразование в 32 бита, да и еще запутался корчое ваше Пипец запутался )))))

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

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