Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 21.10.2010, 11:29
MrDiG MrDiG вне форума
Начинающий
 
Регистрация: 05.10.2010
Сообщения: 112
Репутация: 1227
По умолчанию [Несложно] Помогите освободить ресурсы

Процедура, которая их сохранённой картинки вырезает кусок по координатам и сохраняет в отдельный файл.
Код:
procedure TfrmMain.Crop;
Var L, T, W, H: Integer; bmp: TBitmap; jpg: TJPEGImage;
temponary:string;
Begin
L:=StrToInt(Edit25.Text); // координата X первой точки
T:=StrToInt(Edit26.Text); // координата Y первой точки
W:=StrToInt(Edit27.Text); // координата X второй точки
H:=StrToInt(Edit28.Text); // координата Y второй точки
// координаты не могут быть отрицательными:
If (L<0) Then
      L:=0;
If (T<0) Then
      T:=0;
If (W<0) Then
      W:=0;
If (H<0) Then
      H:=0;
If (L<>W) And (Abs(T-H)>1) Then // проверка не является ли прямоугольник "пустым" (с площадью равной нулю) -- вообще должно быть "And (T<>H)", но в моём модуле JPEG кажется какой-то баг с этим
      Begin
      bmp:=TBitmap.Create; // создаём экземпляр класса TBitmap
      jpg:=TJPEGImage.Create; // создаём экземпляр класса TJPEGImage
      jpg.LoadFromFile('C:\WebBrowserImage.jpg'); // загружаем изображение из jpg-файла
      bmp.Assign(jpg); // конвертируем jpg в bmp (VCL'ские классы сами сделают необходимые преобразования)
      // а вдруг точки перепутали - не левый верхний и правый нижний угол, а как-то по-другому? на всякий случай проверим:
      If L>W Then
            Begin // алгоритм меняющий "местами" значения двух переменных:
            L:=L XOr W;
            W:=L XOr W;
            L:=L XOr W;
            End;
      If T>H Then
            Begin // алгоритм меняющий "местами" значения двух переменных:
            T:=T XOr H;
            H:=T XOr H;
            T:=T XOr H;
            End;
      // а вдруг точки находится за пределами изображения? тоже проверим:
      If (W>=jpg.Width) Then
            W:=jpg.Width-1;
      If (H>=jpg.Height) Then
            H:=jpg.Height-1;
      If (L<W) And (T<H-1) Then // а тут из-за той же баги пришлось дописать "-1"
            Begin
            W:=W-L; // теперь тут не "координата X правого нижнего угла", а ширина прямоугольника
            H:=H-T; // а тут не "координата Y правого нижнего угла", а висота прямоугольника
            BitBlt(bmp.Canvas.Handle, 0, 0, W, H, bmp.Canvas.Handle, L, T, SRCCOPY); // копируем заданную область в левый верхний угол битмапа
            bmp.Width:=W; // уменьшаем его размеры width
            bmp.Height:=H; // и height до размеров заданной области
            jpg.Assign(bmp); // конвертируем обратно в jpg
            jpg.CompressionQuality:=100; // наилучшее качество (максимально возможное с использованием модуля JPEG) - можно задавать в пределах от 1 до 100
            jpg.Compress; // сожмём jpg кодеком

            temponary:='C:\'+inttostr(RandomRange(1,10000)) + '.jpg';
            Edit33.Text:=temponary;

            jpg.SaveToFile(temponary); // сохраняем на диск
            bmp.Free; // очищаем память от уже не нужного экземпляра класса
            jpg.Free; // очищаем память от уже не нужного экземпляра класса
            End
      Else
            ShowMessage('Неправильно задан прямоугольник!');
      End
Else
      ShowMessage('Неправильно задан прямоугольник!');

     Image1.Picture.LoadFromFile(temponary);

End;

Туплю жутко.
Путь сохранения - temponary.
При динамически создаваемом пути - всё отлично.
При статическом - например, C:\abc.jpg - лажа.
Первый раз отрабатывает нормально. Второй раз ругается на то, что файл занят другим процессом. Ресурсы нужно освобождать, это я понимаю. Но что-то всякие вариации с Free - тоже ругаются.

В общем нужно либо придумать способ использовать постоянный путь для сохранения картинки (фактически перезапись без ошибки).
Либо удалять временные файлы при динамическом создании. DeleteFile - что-то ничего не делает.
Ответить с цитированием
  #2  
Старый 21.10.2010, 12:12
Аватар для Aristarh Dark
Aristarh Dark Aristarh Dark вне форума
Модератор
 
Регистрация: 07.10.2005
Адрес: Москва
Сообщения: 2,907
Версия Delphi: Delphi XE
Репутация: выкл
По умолчанию

Попробуй завести 2 различных объекта для считываемой картинки и записываемой.
__________________
Некоторые программисты настолько ленивы, что сразу пишут рабочий код.

Если вас наказали ни за что - радуйтесь: вы ни в чем не виноваты.
Ответить с цитированием
  #3  
Старый 22.10.2010, 01:19
RootDevice RootDevice вне форума
Прохожий
 
Регистрация: 23.08.2010
Адрес: г. Смоленск
Сообщения: 41
Репутация: 10
По умолчанию

Ругается, потому что файл не закрыл.
__________________
Люблю спать, пить пиво за компом, день зарплаты... И что бы все работало само по себе.
Ответить с цитированием
  #4  
Старый 23.10.2010, 16:19
MAD_EVAL MAD_EVAL вне форума
Прохожий
 
Регистрация: 28.11.2009
Сообщения: 16
Репутация: 10
По умолчанию

Открываю
Код:
 F := FileOpen(FILE_NAME, fmOpenWrite OR fmShareDenyWrite);
Работаю.........
Закрываю
Код:
 FileClose(F);

Потом свободно можно переоткрыть и еперзаписать, если я не понял вопроса, поправьте.

И ещё! Лично я, при конвертации в жпег делаю приблизительно такую конструкцию

Код:
      // Создаю
try
      // Преобразовываю
finally
      // Освобождаю через Free
end;

Последний раз редактировалось MAD_EVAL, 23.10.2010 в 17:03.
Ответить с цитированием
  #5  
Старый 26.10.2010, 18:17
RootDevice RootDevice вне форума
Прохожий
 
Регистрация: 23.08.2010
Адрес: г. Смоленск
Сообщения: 41
Репутация: 10
По умолчанию

Послушай. Попробуй сделать вот что. Запомни директоию запуска программы, выполни код, а затем верни директорию на место.
получить директорию:
GETCURRENTDIR
восстановить:
SETCURRENTDIR


Если получится - отпишись. Не получится - тоже. Была такая же проблема с ини файлом. Помогло.
__________________
Люблю спать, пить пиво за компом, день зарплаты... И что бы все работало само по себе.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:07.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025