Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.05.2015, 11:47   #1
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
Вопрос Затемнение изображения JPG

Добрый день!
Создается скриншот формы таким кодом:
Код:
var
 ScreenDC:HDC;
 Canvas:TCanvas;
 myjpg:  TJPEGImage;
 Image: TImage;
 i, j: integer;
begin
 Image:=TImage.Create(nil);
 myjpg:= TJPEGImage.Create;
 ScreenDC := GetDC(0);
 Canvas:=TCanvas.Create();
 Canvas.Handle:=ScreenDC;
 Image.Width := Form_Main.Width;
 Image.Height := Form_Main.Height;
 Image.Canvas.CopyRect(Rect(0, 0, Image.Width, Image.Height), Canvas,
                                 Rect(0, 0, Form_Main.Width, Form_Main.Height));
 ReleaseDC(0,ScreenDC);
 myjpg.Assign(Image.Picture.Bitmap);
 myjpg.compressionquality:=75;
 myjpg.compress;
 myjpg.SaveToFile(ExtractFilePath(ParamStr(0)) + '_.jpg');
 Image.Free;
 Canvas.Free;
Потом мне надо его загрузить и затемнить. Использую такой код:
Код:
 for i:=0 to Form_Main.sImage2.Width do
 for j:=0 to Form_Main.sImage2.Height do
  Form_Main.sImage2.Canvas.Pixels[i,j]:=
                        ChangeColor(Form_Main.sImage2.Canvas.Pixels[i,j],false);
Код срабатывает, но только если в sImage2 загружен BMP файл. А его не могу использовать, т.к. сохраненный скрин BMP файла получается 8мб и из-за этого процесс затемнения не быстро идет.
Как можно сделать затемнение если загружен JPG файл?
Функция:
Код:
function ChangeColor(InputColor: TColor; Lighten: Boolean): TColor;
const
 col=60;
 var
   r,g,b: extended;
 begin
   r := GetRValue(InputColor);
   g := GetGValue(InputColor);
   b := GetBValue(InputColor);
  if Lighten = True then
   begin
     r := r+col; g := g+col; b := b+col;
   end else
   begin
     r := r-col; g := g-col; b := b-col;
   end;
  if r > 255 then r := 255;    if r < 0 then r := 0;
   if g > 255 then g := 255;   if g < 0 then g := 0;
   if b > 255 then b := 255;   if b < 0 then b := 0;
  Result := RGB(byte(Round(r)),byte(Round(g)),byte(Round(b)));
 end;
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 02.05.2015, 11:54   #2
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,949
По умолчанию

Уточняющий вопрос:
Почему именно такой код?
Код:
r := GetRValue(InputColor);
g := GetGValue(InputColor);
b := GetBValue(InputColor);
***
r := r+col; g := g+col; b := b+col;
***
if r > 255 then r := 255;    if r < 0 then r := 0;
if g > 255 then g := 255;   if g < 0 then g := 0;
if b > 255 then b := 255;   if b < 0 then b := 0;
Я обычно использую:
Код:
col:=Canvas.Pixels[i,j];
r:=GetRValue(col);
g:=GetGValue(col);
b:=GetBValue(col);
r:=Round(r+(255-r)*prozr);
g:=Round(g+(255-g)*prozr);
b:=Round(b+(255-b)*prozr);
Canvas.Pixels[i,j]:=RGB(r,g,b);
Код:
r:=Round(r-r*prozr);
g:=Round(g-g*prozr);
b:=Round(b-b*prozr);
Цитата:
если загружен JPG файл
Это бесполезно. Я даже пробовал линию прочертить (MoveTo/LineTo) - выдает ошибку
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]

Последний раз редактировалось newerow1989; 02.05.2015 в 12:07.
newerow1989 вне форума Ответить с цитированием
Старый 02.05.2015, 12:18   #3
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

А как тогда уменьшит размер bmp файла скриншота?
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 02.05.2015, 12:27   #4
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,949
По умолчанию

Я думаю ввести пропорцию:
Код:
Canvas.Pixels[x,y]:=Canvas.Pixels[Round(i*Width1/Width2),Round(j*Height1/Height2)];
Примерно как-то так
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]
newerow1989 вне форума Ответить с цитированием
Старый 02.05.2015, 12:30   #5
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
Вопрос

Цитата:
Сообщение от newerow1989 Посмотреть сообщение
Я думаю ввести пропорцию:
Код:
Canvas.Pixels[x,y]:=Canvas.Pixels[Round(i*Width1/Width2),Round(j*Height1/Height2)];
Примерно как-то так
В какое место?
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 02.05.2015, 12:48   #6
newerow1989
Я самый любопытный
Участник клуба
 
Аватар для newerow1989
 
Регистрация: 24.07.2012
Сообщений: 1,949
По умолчанию

После загрузки картинки в sImage2.
Про размерность у компонента есть свойства Proportional, Stretch.

Если каждый пиксел картинки изменять, то этот процесс будет долгим. Лучше будет, если размер поменьше сделать (если возможно)
С запрограммированным приветом, Неверов Евгений!
Сайт: http://newerow1989.ru
[Паскаль] [Delphi]

Последний раз редактировалось newerow1989; 02.05.2015 в 12:53.
newerow1989 вне форума Ответить с цитированием
Старый 02.05.2015, 13:12   #7
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Цитата:
Сообщение от newerow1989 Посмотреть сообщение
После загрузки картинки в sImage2.
Про размерность у компонента есть свойства Proportional, Stretch.

Если каждый пиксел картинки изменять, то этот процесс будет долгим. Лучше будет, если размер поменьше сделать (если возможно)
Так вот я и спрашиваю: каким образом можно уменьшить размер конечного файла?
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 02.05.2015, 15:12   #8
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

А так быстрее не станет?
Код:
procedure TForm1.Button1Click(Sender: TObject);
const
  col = 60;
var
  bmp: tbitmap;
  i, j, dx: integer;
  t: tdatetime;
  Pixels: PByteArray;
begin
  bmp := GetFormImage;
  bmp.PixelFormat := pf24bit;
  t := now;
  dx := DWord(bmp.ScanLine[1]) - DWord(bmp.ScanLine[0]);
  Pixels := bmp.ScanLine[0];
  for i := 0 to bmp.Height - 1 do
  begin
    for j := 0 to bmp.Width - 1 do
    begin
      Pixels[j * 3] := max(0, Pixels[j * 3] - col); // blue
      Pixels[j * 3 + 1] := max(0, Pixels[j * 3 + 1] - col); // green
      Pixels[j * 3 + 2] := max(0, Pixels[j * 3 + 2] - col); // red
    end;
    inc(DWord(Pixels), dx);
  end;
  caption := FormatDateTime('s.zzz', now - t);
  bmp.SaveToFile(ExtractFilePath(ParamStr(0)) + '1.bmp');
  bmp.Free;
end;
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 02.05.2015, 15:39   #9
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Спасибо, BDA, я попробую потом твой код. Я тут в одной из своих старых тем нашел, что в свое время мне надо было уменьшить файл. Мне там написали решение в виде создания сначала BMP файла, а потом его перегонки в JPG и сохранение в BMP файл. Это делает вот такая функция:
Код:
procedure GetRS(RS:TBitmap; Path: string);
var
 c: TCanvas;
 r: TRect;
 jpgImg: TJPEGImage;
begin
 c:=TCanvas.Create;
 c.Handle:=getWindowDC(GetDesktopWindow);
 try
  r:=Rect(0,0,Form_Main.Width,Form_Main.Height);
  RS.Width:=Form_Main.Width;
  RS.Height:=Form_Main.Height;
  RS.Canvas.CopyRect(r,c,r);
  RS.SaveToFile(Path);
  jpgImg:=TJPEGImage.Create;
  jpgImg.Assign(RS);
  jpgImg.SaveToFile(Path)
 finally
  ReleaseDC(0,c.Handle);
  c.Free;
  jpgImg.Free;
 end;
end;
Теперь сохраненный BMP файл получается около 200КБ. Меня это конечно устраивает.
Использую я эту функцию так:
Код:
var
 b: TBitMap;
 i,j: integer;
begin
 b:=TBitMap.Create;
 GetRS(b,ExtractFilePath(ParamStr(0)) + '_.bmp');
 b.Free;
 Form_Main.sImage2.Picture.Bitmap.LoadFromFile(ExtractFilePath(ParamStr(0)) + '_.bmp');
end;
Но теперь я не могу его загрузить в Image. Выдается ошибка "Bitmap is not valid image". Что надо исправить?
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 02.05.2015, 15:53   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Потому что в файле находится изображение в формате jpeg, а не bmp.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Написать программу алгоритм для открытия изображения BMP, PNG, JPG Rubelka Помощь студентам 5 10.12.2014 15:41
Перемещая папки с экзел файлом и jpg картинками, ссылки на jpg не работают?? Igorilla Microsoft Office Excel 0 16.03.2013 21:36
Изменение разрешения изображения .jpg Nina+ Общие вопросы C/C++ 2 21.06.2012 22:28
Затемнение экрана Renok Общие вопросы Delphi 1 02.05.2012 19:16
Сохранение заданий на печать в файл изображения JPG DimD Фриланс 1 15.04.2009 19:27