Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

JPEG большого размера   Найти похожие ветки 

 
danja12   (2003-09-05 10:42) [0]

Необходимо копировать в TImage произвольные прямоугольные куски JPEG-файла размером от 2-х до 3-х Mb. (соответствующий BMP 40-50 Mb)

BMP := TBitMap.Create;
Jpg := TJpegImage.Create;
Jpg.LoadFromFile(NP);
BMP.Assign(JPG);
Image1.Canvas.CopyRect(RWP , BMP.Canvas, RPP);
Jpg.Free;
BMP.Free;

В момент BMP.Assign(JPG) выдается ошибка EOutOfResurces : Параметр задан неверно.  Причем иногда отрабатывает, а иногда нет. Добавление BMP.Dormant; BMP.FreeImage; не помогает.

Можно ли в пинципе работать с такими объемами?


 
ZEE ©   (2003-09-05 11:02) [1]

вместо
BMP.Assign(JPG);
пиши
BMP.Width:=JPG.Width;
BMP.Height:=JPG.Height;
BMP.Canvas.Draw(0,0,JPG);


 
dzmitry_   (2003-09-05 11:52) [2]

угу... круто будет если
JPG.Width:=8000
на
JPG.Height:=6000 - оут оф ресурс...
ещё варианты...


 
ZEE ©   (2003-09-05 12:24) [3]

тогда ищи инфу по формату Jpeg, потом залазь в файл и вытаскивай прям из него нужный тебе кусок...
только, подозреваю, это будет гемор...


 
danja12   (2003-09-05 13:47) [4]

На самом деле, самый интересный вопрос это: почему после перезагрузки машины первые 3 или 4 раза код отрабатывает и только потом грохается. Значит, не смотря на


BMP.ReleaseHandle;
BMP.Free;


память не освобождается! И что поэтому поводу можно сделать?


 
ZEE ©   (2003-09-05 15:03) [5]

а если так
try
 BMP := TBitMap.Create;
 Jpg := TJpegImage.Create;
...

finally
 Jpg.Free;
 BMP.Free;
end;

может просто где-то до Free обработка "срывается" и до освобождения памяти дело не доходит...


 
danja12   (2003-09-05 16:22) [6]

Вообще то, освобождение памяти у меня стоит в блоке try-finally.
Я для простоты здесь не привел полный текст, видимо зря - чтобы не возникало лишних вопросов.
А потом, в отладчике когда исполняю пошагово, она выполняется.
А как уничтожить объект, кроме как Free ?


 
ZEE ©   (2003-09-05 17:17) [7]

Destroy


 
danja12   (2003-09-08 09:00) [8]

Насколько я знаю, Free как раз и вызывает Destroy, предварительно проверив не равен ли объект nil, так что вряд ли это поможет. Мне кажется, я что-то недопонимаю в BMP.Dormant; BMP.FreeImage;
Но все равно, спасибо.


 
ZEE ©   (2003-09-08 11:07) [9]


> danja12   (08.09.03 09:00) [8]
> Насколько я знаю, Free как раз и вызывает Destroy, предварительно
> проверив не равен ли объект nil

это правильно, просто до этого ж был вопрос "А как уничтожить объект, кроме как Free ?"
так вот Destroy - тоже вариант...
еще есть
procedure FreeAndNil(var Obj);
но это все-равно тоже самое


 
dzmitry_   (2003-09-08 11:20) [10]

кстати, я исправляюсь... я сделал так, и сработало

BMP.Width:=1024;
BMP.Height:=768;
BMP.Canvas.Draw(-100,-100,JPG);

вывести из JPG в BMP кусок от 100,100 с шириной 1024 и высотой 768


 
danja12   (2003-09-08 12:44) [11]

Спасибо всем! (Это не значит что я закрываю тему, т.к. положительного результата пока нет :)

> ZEE ©  (08.09.03 11:07) [9]
Прошу прощения за некорректные высказывания и вопросы - мало опыта в таком общении, редко здесь бываю. Вопрос об освобождении памяти у меня пока открыт: программа отрабатывает 3-5 раз, затем нехватает ресурсов. Последнее достижение - не надо перезагружаться, только перезапустить программу (выкинул BMP.Dormant; BMP.FreeImage;).

> dzmitry_  (08.09.03 11:20) [10]
Попробую Ваш вариант, правда у меня BMP.Width:=3947; и
BMP.Height:=3947;
так что шансов немного. Кстати, в соседней ветке, слышал от Вас слово "картография" и, если есть желание или нужда, можем пообмениваться опытом. Я сейчас пытаюсь в свой картографический редактор подсунуть растровую подложку - уперся в объем jpg-файлов планшетов.


 
Александр-И ©   (2003-09-09 01:56) [12]

А если так:

 jpgTMP := TJPEGImage.Create;
 jpgTMP.LoadFromFile("Foto.jpg");
 ImageBMP.Canvas.Draw(-2000,-800,jpgTMP);

//ImageBMP : TImage - т.е. не TBitMap

//Исходный размер Foto.jpg - 6500х4500 - больше у меня под рукой не оказалось

Я попробовал - все работает


 
danja12   (2003-09-10 10:14) [13]

> Александр-И ©  (09.09.03 01:56) [12]
Александр, уточнили бы на каком этапе Вы устанавливаете размеры ImageBMP У меня как только ImageBMP.Height := 3947; ImageBMP.Width := 3947; так сразу OutOfResource! А если не устанавливаете или Stretch = True, так отчего бы и не работать.
То же самое dzmitry_ : 1024 * 768 может и прокатит, да не может, а точно, а вот четыре на четыре тысячи - нет.
Вот чего не знаю, так может опцию в проекте какую поставить, или в видяхе дело - сам сталкивался с такими глюками ?


 
ZEE ©   (2003-09-10 10:21) [14]

[13] - не в видяхе дело, если ты это в памяти все делаешь, но если конечно ты это все например в Image1.Picture.Bitmap прям на видимой форме пихаешь - то может и видяха, хотя нет все-равно на экран все 3947х3947 не влезут (или у тебя супер навороченый монитор с охрененным разрешением...)


 
dzmitry_   (2003-09-10 11:26) [15]

а интересно, существует ли компонент/класс по работе с изображениями, но не загружающие сразу всё в оперативку... буду искать, о результатах сообщу...


 
danja12   (2003-09-10 12:20) [16]

> ZEE ©  (10.09.03 10:21) [14]
То что железо не причем, по Вашему мнению, это радует ! (А вот у меня был случай еще на первых Делфях, что программа выводила иконки на принтер только если видяха S3 и никакая другая.)
И, нет монитор у меня обычный и видео обычное - я на всякий случай спросил.

> dzmitry_  (10.09.03 11:26) [15]
Спасибо, было бы интересно.

А по теме - вот: Код грохается на 4-й раз, даже если Битмап размером 100 на 100, а картинку из JPEG"а я в него кидаю методом StretchDraw, т.е. за ошибку отвечает именно JPEG. Может надо использовать второй компонент модуля: TJPEGData?


 
dzmitry_   (2003-09-10 13:09) [17]

вот почему код падает, это не ясно... тут надо глядеть исходник, что бы сказать точно... может утечка какая неприметная...
среди компонентов я нашёл только вывод больших битмап в 256 цветов... исходник пока гляну, но вот я не смог сгененрировать самостоятельно картинку размером больше 15 на 15 тыс... я больше встречал, но то делал не я... не такая уж и простая задачка оказывается


 
danja12   (2003-09-10 13:54) [18]

Копаю дальше: нет никакой разницы между двумя вариантами 1) когда Jpeg - создается, используется и уничтожается в прцедуре, т.е. является локальной переменной и 2) когда он создается в главной форме, уничтожается при ее закрытии, а в проседуре только гружу в него из файла и копирую его в канву, тогда он глобальная переменная и в проседуре нет никаких Jprg.Free.


 
Александр-И ©   (2003-09-11 03:02) [19]

>danja12   (10.09.03 10:14) [13]
>Александр, уточнили бы на каком этапе Вы устанавливаете размеры >ImageBMP У меня как только ImageBMP.Height := 3947; >ImageBMP.Width := 3947; так сразу OutOfResource! А если не >устанавливаете или Stretch = True, так отчего бы и не работать.
>То же самое dzmitry_ : 1024 * 768 может и прокатит, да не >может, а точно, а вот четыре на четыре тысячи - нет.
>Вот чего не знаю, так может опцию в проекте какую поставить, >или в видяхе дело - сам сталкивался с такими глюками ?


А-а-а, батенька, так у вас размер bmp 4000х4000 ! Я сразу не понял. Так причем здесь jpg? Если вы без всякого jpg просто захотите что-нибудь сделать с bitmap такого размера, (например покрасить в зеленый цвет FillRect), так будет та же ошибка - EOutOfResurces.
Я вот поэксперментировал : (у меня 128М) - при HighColor(16 бит) проходят операции с картинкой ~2000х4000, а если установить TrueColor(24 бит) - то только 2000х2000.

Разделяю любопытство коллеги ZEE - а зачем такой большой bmp, если все равно в экран не влазит?


 
ZEE ©   (2003-09-11 10:18) [20]

да это конечно любопытно, но подозреваю что это карты...


 
danja12   (2003-09-11 11:34) [21]

> Александр-И ©  (11.09.03 03:02) [19]
> А-а-а, батенька, так у вас размер bmp 4000х4000 ! Я сразу не
> понял. Так причем здесь jpg?

Я тоже не пойму, правда, теперь причем тут bmp. Размер jpg мне задан извне - приносят отсканированные планшеты с нужным им разрешением и качеством. Это растровая подложка под векторную карту. Теперь мне надо нужный кусок подложки подпихнуть в нужном месте карты. Ничего лучше Canvas.CopyRect(RectDest, BMP.Canvas, RectRes); придумать не смог - решение в лоб, что называется. Но у jpg нет канвы, отсюда Jpg.LoadFromFile(NP); BMP.Assign(JPG); (см. с чего все началось). В этом случае размер bmp становится равным jpg. Если делать как предлагаете Вы :
jpgTMP := TJPEGImage.Create;
jpgTMP.LoadFromFile("Foto.jpg");
ImageBMP.Canvas.Draw(-2000,-800,jpgTMP);

встает вопрос о размерах bmp или я чего-то еще не понимаю?


 
dzmitry_   (2003-09-11 11:39) [22]

>Александр-И ©   (11.09.03 03:02) [19]
>Разделяю любопытство коллеги ZEE - а зачем такой большой bmp, если все равно в экран не влазит?
тогда сам вопрос, а как вывести ЧАСТЬ этой самой карты, не грузя всё сразу?.. и ещё было указано, ну получаются такие, и меньше нельзя сделать


 
danja12   (2003-09-11 12:41) [23]

> dzmitry_  (11.09.03 11:39) [22]
Спасибо большое, письмо получил, а вот с ответом - заминка - на работе сейчас нечасто появляюсь, и ящик то случайно проверил, но в ближайшие день-два обязательно.

Натолкнулся тут на демо-проект по Jpg прямо в Делфи, попробовал приспособить под свои нужды - вылезла таже самая ошибка: can only modify an image if it contains a bitmap raise EInvalidOperation при попытке скопировать кусок канвы. Как в анекдоте: смотреть можно, трогать нельзя.


 
Sapersky ©   (2003-09-11 14:43) [24]

Распилить эту подложку на мелкие тайлы и грузить/выводить так.


 
ZEE ©   (2003-09-11 15:11) [25]

> Sapersky ©   (11.09.03 14:43) [24]
если почитаешь пред. посты - увидишь, что после нескольких "распиливаний" програма выдает EOutOfResurces


 
Sapersky ©   (2003-09-11 16:18) [26]

Код грохается на 4-й раз, даже если Битмап размером 100 на 100

Это что ли? Это к теме (как работать с большими изображениями) как раз не относится. Обычные глюки.


 
danja12   (2003-09-11 17:19) [27]

Если это кого-нибудь на что-нибудь натолкнет, то вот:
Делаю так, как давно предлагал Александр-И ©  (09.09.03 01:56) см.[12]. Т.е. с битмапами и Jpg-ми не связываюсь совсем, в смысле TJpegImage не использую, подключаю модуль JPEG и сразу гружу ImageJPG.Picture.LoadFromFile(FileName). Затем на основной имидж Image.Canvas.Draw(X, Y, ImageJPG.Picture.Graphic);. Смещение X, Y высчитываю, чтобы все легло как надо. Результат тот же самый: оут_оф_ресурс. Как говориться, что совой об пень, что пнем о сову, а все равно сове как-то непосебе.
А демонстрашка делфовская с моими Jpeg-ами, работает хоть бы что, но там имидж в скрулбоксе и поэтому не надо всякие смещения вводить. Правда если ее запускать после того как мой код грохнулся, то и она вслед за ним и тоже через раз. Пойду на другую машину с другими виндами что-ли.


 
dzmitry_   (2003-09-12 08:43) [28]

а какая Виноуз и какие Дельфи?
может просто Дельфи добитое попалось... урезаное пиратами до чёртиков...


 
danja12   (2003-09-12 09:16) [29]

> dzmitry_  (12.09.03 08:43) [28]
Винды - 98 версия [4.10.2222] Делфи 6 (CD Dynamite SoftGroup). До сего момента принципиальных глюков не отлавливал. Работаю в одиночку - сходить глянуть на другом рабочем месте некуда.
За архив спасибо - правда, не знаю, под шестеркой пойдет или нет.

А вообще, подозрение у меня на то, что в худшем варианте - когда пользователь залез на стык планшетов, мне их нужно выводить до 4-х штук сразу. Потому как, если память мне не изменяет, пока ползаешь по одному планшету и, он даже каждый раз подгружается заново, все работает нормально и в варианте Jpg -> Bmp -> Canvas.CopyRect и в варианте Image1.Picture -> Image2.Canvas.Draw


 
Sapersky ©   (2003-09-12 11:22) [30]

Ну вот вам вариант. Используется KOL (http://bonanzas.rinet.ru/kol.zip) и JpegObj для него (http://bonanzas.rinet.ru/kolJpegObj.zip). Грузится 4096*4096, рисуется прямо на форму (она пустая), мышь с зажатой левой кнопкой - перемещение по изображению.
Фича здесь в том, что изображение вручную копируется в буфер из jpeg (Draw2Bmp). Поэтому и KOL (у стандартного jpeg"а нет scanlines).

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, ExtCtrls,
 Kol, JpegObj;

type
 TForm1 = class(TForm)
   procedure FormShow(Sender: TObject);
   procedure FormHide(Sender: TObject);
   procedure FormPaint(Sender: TObject);
   procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
     Y: Integer);
   procedure FormResize(Sender: TObject);
 private
   procedure Draw2Bmp;
 end;

var
 Form1: TForm1;
 jp : PJpeg = nil;
 b : PBitmap = nil;
 Pos : TPoint = (x: 0; y: 0);
 MaxPos, OldMousePos : TPoint;
 FirstTime : Boolean = True;

implementation

{$R *.DFM}

procedure TForm1.FormShow(Sender: TObject);
begin
jp:=NewJpeg;
jp.PixelFormat:=jf24Bit;
jp.LoadFromFile("pic.jpg"); jp.DIBNeeded;
b:=NewBitmap(Form1.Width,Form1.Height); b.PixelFormat:=pf24bit;
end;

procedure TForm1.FormHide(Sender: TObject);
begin
b.Free; jp.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
If b<>nil then b.Draw(Form1.Canvas.Handle,0,0);
end;

procedure TForm1.Draw2Bmp;
Var y : Integer;
   p : PByte;
begin
If Pos.x<0 then Pos.x:=0; If Pos.y<0 then Pos.y:=0;
If Pos.x>MaxPos.x then Pos.x:=MaxPos.x; If Pos.y>MaxPos.y then Pos.y:=MaxPos.y;

For y:=0 to Form1.Height-1 do begin
 p:=PByte(jp.Bitmap.ScanLine[Pos.y+y]);
 Inc(p,Pos.x*3);
 Move(p^,b.ScanLine[y]^,b.ScanLineSize);
end;
FormPaint(nil);
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
 Y: Integer);
begin
If (ssLeft in Shift) then
 If not (FirstTime) then begin
   Inc(Pos.x, OldMousePos.x-X); Inc(Pos.y, OldMousePos.y-Y);
   Draw2Bmp;
 end else FirstTime:=False;

OldMousePos.x:=X; OldMousePos.y:=Y;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
If (jp<>nil) and (Form1.Width>0) and (Form1.Height>0) then begin
 MaxPos.x:=jp.Width-Form1.Width; MaxPos.y:=jp.Height-Form1.Height;
 b.Width:=Form1.Width; b.Height:=Form1.Height; b.PixelFormat:=pf24bit;
 Draw2Bmp;
end;
end;

end.


 
ZEE ©   (2003-09-12 17:03) [31]

danja12   (11.09.03 17:19) [27]
Т.е. с битмапами и Jpg-ми не связываюсь совсем, в смысле TJpegImage не использую, подключаю модуль JPEG и сразу гружу ImageJPG.Picture.LoadFromFile(FileName). Затем на основной имидж Image.Canvas.Draw(X, Y, ImageJPG.Picture.Graphic);
все-равно TJpegImage используешь - при ImageJPG.Picture.LoadFromFile("...jpg") картинка как раз в TJpegImage грузится, который подставляется в Picture.Graphic
и TBitmap тоже пользуешь - Image.Canvas.Draw() не будет работать если у тебя в Picture.Graphic нет TBitmap


 
danja12   (2003-09-15 09:38) [32]

> ZEE ©  (12.09.03 17:03) [31]
Да это, вобщем, понятно, имелось в виду: не использую явно в своем коде TJpegImage.Create. Иногда черте-что влияет на исполняемость кода (у меня, почему-то просто безобразно ведут себя  модули с "Q": QPrinters, QClipbrd, а стандартные - нормально).
Но к делу: абсолютно точно все работает, пока грузится только один планшет, как только залез на стык, так - труба. Возникает подозрение, что я пытаюсь загрузить следующий рисунок, а предыдущий еще не отрисовался, но что с этим сделать ума не приложу (а надо бы :)


 
ZEE ©   (2003-09-15 11:43) [33]

>danja12   (15.09.03 09:38) [32]
>Возникает подозрение, что я пытаюсь загрузить следующий рисунок, а предыдущий еще не отрисовался
может TImage.OnProgress поможет...
всмысле Stage отслеживать или PercentDone


 
danja12   (2003-09-17 12:17) [34]

> ZEE ©  (15.09.03 11:43) [33]
Отслеживаю. Доотслеживался, что кажется понял в чем дело: больше всего похоже, что есть некие ограничения на размер TCanvas. Дело оказалось не в стыках планшетов, а в том что у меня карта, а в ней масштаб отображеня - плавающий, и при наезде (приближении) край картинки уходит далеко за край экрана (TImage.Canvas), вот в этот момент все и грохается. Тоже самое было и на стыках, то есть когда близко к одному краю, от второго далеко, но это уже, как говориться, чисто мои трудности.


 
dzmitry_   (2003-09-17 13:51) [35]

>больше всего похоже, что есть некие ограничения
>на размер TCanvas
попробуй на NT/200/ХР, возможно что не хватает ресурсов, хотя может есть ограничение и самих форматов, мне например так и не удалось создать .bmp файл размеров 2Г... а это не такое уж и большое изображение получается в итоге...


 
Denis555   (2003-12-15 11:25) [36]

Сталкивался с такой бедой, нужно было оперировать с картинками формата А2 отсканеренными с 300dpi, TImage нивкакую не хотел их грузить, а если и загрузит то дальше при операциях все вылетало с Out of resurses
так вот выход нашел в использовании во первых TImage32 (ошибок вообще не вылетало никогда, но из-за сильно урезанных возможностей TCanvas пришлось от него отказаться) и во вторых ImageLib - этот компонент существенно отодвинул границу "Out of resurses", но не устранил ее совсем :(


 
Denis555   (2003-12-15 15:37) [37]

так вот задолбала меня это "нехватка памяти" и сделал вот что - если при увеличении размера в высоту или ширину у меня вылетает exception я сохраняю эту картинку на диск, затем тут же ее открываю и снова пытаюсь увеличить размеры - все тип топ. компонент TPMultiImage из ImageLib


 
CyberStorm   (2003-12-17 19:47) [38]

Ограничения в Win9x/ME для координат GDI +-32767, при работе с большими растрами частенько в эти ограничения все уприрается



Страницы: 1 вся ветка

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.03 c
1-1082555935
ser_ega
2004-04-21 17:58
2004.04.11
Stringgrid


6-1079419590
pavlov
2004-03-16 09:46
2004.04.11
Передача сообщение на другой компьютер


11-1058608108
Dentall
2003-07-19 13:48
2004.04.11
Динамическое создание формы в KOL


1-1079865144
Powerland Software
2004-03-21 13:32
2004.04.11
подмена кода DLL


3-1078502443
Александр Крючков
2004-03-05 19:00
2004.04.11
Работа с блоб-полями через TClientDataSet