Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
1
Delphi 6-7

Зернистость

30.05.2020, 13:25. Показов 1536. Ответов 19

Author24 — интернет-сервис помощи студентам
Здравствуйте, хотел попробовать сделать эффект с изменением зернистости экрана, но выходит Runtime error. Изменять код пробовал (может быть не все, я тупой, сори).
Вот код:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
 
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  bmp: tbitmap;
dc: hdc;
 
implementation
 
{$R *.dfm}
procedure dither(var bitmap:tbitmap);
type
trgb = record
r,g,b: byte;
end;
argb = array[0..1] of trgb;
pargb = ^argb;
var x,y:integer;
p:pargb;
b:tbitmap;
begin
bitmap.pixelformat := pf24bit;
b:=tbitmap.create;
b.assign(bitmap);
for y:=0 to b.height-1 do
begin
p := b.scanline[y];
for x := 0 to b.width-1 do
begin
if (p[x].r>30)and(p[x].r<225) then p[x].r:=p[x].r-30+random(60);
if (p[x].g>30)and(p[x].g<225) then p[x].g:=p[x].g-30+random(60);
if (p[x].b>30)and(p[x].b<225) then p[x].b:=p[x].b-30+random(60);
end;
end;
bitmap.canvas.draw(0,0,b);
end;
begin
while true do begin
dither(bmp);
Sleep(500);
end;
end.
Что тут не так? И если можно то скиньте как правильно, пожалуйста.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.05.2020, 13:25
Ответы с готовыми решениями:

Зернистость в фильмах
Как убрать зернистость в фильмах?

Зернистость на мониторе
Добрый день, уважаемые форумчане. Система: ЦП : QuadCore Intel Core i7-3770, 3900 MHz (39 x...

Зернистость на чёрном фоне
недавно начала бросаться в глаза зернистость изображения в играх вот пример: отмечены...

GTX 690 зернистость и цвет
Менял настройки в видеокарте ( мультипроцессорный рендеринг в часности и еще что не помню) для...

19
Модератор
3629 / 2150 / 759
Регистрация: 15.11.2015
Сообщений: 8,631
30.05.2020, 15:09 2
Цитата Сообщение от AnCo666 Посмотреть сообщение
trgb = record
r,g,b: byte;
end;
Хоть тип указан byte, но адрес каждыого элемента выравнивается на 4. То есть, запись выходит за пределы памяти изображения.
Попробуй так:
Delphi
1
2
3
4
type
  trgb = packed record
    r,g,b: byte;
  end;
1
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
30.05.2020, 16:11  [ТС] 3
К сожалению ничего не изменилось, так же Runtime error, синим выделяется
Delphi
1
b:=tbitmap.create;
, хотя вроде все правильно
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
30.05.2020, 16:38 4
Где создание и инициализация bmp? Что за while true и Sleep()?

Добавлено через 27 секунд
Почему у формы ни единого метода? Какова цель?

Добавлено через 1 минуту
Под Windows не RGB, а BGR. И такой тип уже есть, свой не надо было объявлять: TRGBTriple & PRGBTriple.
1
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
30.05.2020, 17:00  [ТС] 5
while true это бесконечный цикл, sleep пауза
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
30.05.2020, 18:50 6
Это было риторически. Так в принципе не делается.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
Unit Unit1;
 
Interface
 
Uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  ExtCtrls;
 
Type
  TForm1 = Class(TForm)
    Timer1: TTimer;
    Procedure FormCreate(Sender: TObject);
    Procedure FormDestroy(Sender: TObject);
    Procedure FormResize(Sender: TObject);
    Procedure FormPaint(Sender: TObject);
    Procedure Timer1Timer(Sender: TObject);
  Private
    FBackGround: TBitmap;
    FBackDither: TBitmap;
  End;
 
Var
  Form1: TForm1;
 
Implementation
 
{$R *.dfm}
 
Procedure Dither(ABitmap: TBitmap);
Const
  MAX_BYTE = 255;
  LIM_DECREASE = 30;
  LIM_INCREASE = 30;
Var
  x, y: Integer;
  PPixel: PRGBTriple;
Begin
ABitmap.PixelFormat := pf24bit;
For y := 0 To Pred(ABitmap.Height) Do
  Begin
  PPixel := ABitmap.ScanLine[y];
  For x := 0 To Pred(ABitmap.Width) Do
    Begin
    If (PPixel.rgbtRed > LIM_DECREASE) And (PPixel.rgbtRed < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtRed := PPixel.rgbtRed - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    If (PPixel.rgbtGreen > LIM_DECREASE) And (PPixel.rgbtGreen < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtGreen := PPixel.rgbtGreen - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    If (PPixel.rgbtBlue > LIM_DECREASE) And (PPixel.rgbtBlue < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtBlue := PPixel.rgbtBlue - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    Inc(PPixel);
    End;
  End;
End;
 
Procedure TForm1.FormCreate(Sender: TObject);
Begin
DoubleBuffered := True;
FBackDither := TBitmap.Create();
FBackGround := TBitmap.Create();
FBackGround.LoadFromFile('...');
FBackGround.PixelFormat := pf24bit;
Timer1.Interval := 75;
End;
 
Procedure TForm1.FormDestroy(Sender: TObject);
Begin
FreeAndNil(FBackGround);
FreeAndNil(FBackDither);
End;
 
Procedure TForm1.FormResize(Sender: TObject);
Begin
Repaint();
End;
 
Procedure TForm1.FormPaint(Sender: TObject);
Begin
Canvas.Draw(0, 0, FBackGround);
Canvas.Draw(330, 130, FBackDither);
End;
 
Procedure TForm1.Timer1Timer(Sender: TObject);
Begin
FBackDither.Assign(FBackGround);
Dither(FBackDither);
Repaint();
End;
 
End.
1
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
30.05.2020, 19:08  [ТС] 7
Теперь вообще ничего не происходит (боже, какой я тупой, простите)
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
30.05.2020, 20:13 8
Могу предположить, что вы скопировали этот код, не создав обработчиков событий у формы.

Добавлено через 3 минуты
Можно описать/добавить метод Procedure FormCreate(Sender: TObject); в класс и скопировать реализацию этого метода Procedure TForm1.FormCreate(Sender: TObject); {...}, но само оно не подключится к событию.

Добавлено через 8 минут
Инспектор объектов, вкладка "События".
Двойной клик в пустой ячейке колонки справа не только генерирует метод для события, но и подключает его как обработчик события.
Каждая ячейка справа это выпадающий список, там будут все методы класса подходящие по заголовку (набору параметров).
Многие объекты при двойном клике на сам объект в design-time'е имеют событие генерируемое по умолчанию.
Например двойной клик по форме создаст OnCreate для формы. А двойной клик по кнопке генерирует OnClick для кнопки.
2
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
30.05.2020, 20:17 9
То есть нужно сделать чтоб все обработчики
  • FormCreate
  • FormDestroy
  • FormResize
  • FormPaint
  • Timer1Timer
были выбраны у соответствующих объектов.
Миниатюры
Зернистость  
2
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
31.05.2020, 07:33  [ТС] 10
Что-то такое получилось
Миниатюры
Зернистость   Зернистость   Зернистость  

0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
31.05.2020, 14:39 11
Ну так если ошибку пишет, хорошо бы в неё вчитаться?
Имя вашего файла поставьте, относительный или (желательно) полный путь.
0
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
31.05.2020, 18:07  [ТС] 12
А зачем имя файла ставить, если я хочу прямо на Desktope менять зернистость?
0
Модератор
3629 / 2150 / 759
Регистрация: 15.11.2015
Сообщений: 8,631
31.05.2020, 19:54 13
AnCo666, тогда зачем пытаться открыть файл 'D:\Зернистость', который в общем и не файл?
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
31.05.2020, 21:29 14
Ваш код делает некий случайный дизеринг переданному BMP-файлу.
Что значит "прямо на Desktope менять зернистость"?
0
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
01.06.2020, 05:18  [ТС] 15
Ну то есть прямо поверх всех окон, как будто с монитором проблемы, я незнаю как обьяснить
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
02.06.2020, 01:09 16
хм... Я вас понял.
Но тут есть два основных варианта:
  1. Просто сделать один раз скриншот экрана и использовать его (так делают большинство скринсейверов);
  2. Или же есть необходимость получения "актуального"/"текущего" изображения каждый момент времени (тут уже сложнее);

Добавлено через 3 минуты
Можно попробовать сделать слоёное окно... И добиваться нужного эффекта наложением некоторого "полупрозрачного шума"...

Добавлено через 2 минуты
Тут возможно даже через обычный AlphaBlendValue пойдёт... Надо обдумать...
0
Модератор
3629 / 2150 / 759
Регистрация: 15.11.2015
Сообщений: 8,631
02.06.2020, 02:02 17
AnCo666, тебе же уже показали, как снять скриншот, внести изменения и вывести картинку обратно на экран Изменение оттенка пикселей.
1
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
02.06.2020, 02:47 18
Лучший ответ Сообщение было отмечено AnCo666 как решение

Решение

Если по мотивам того сообщения... То это вариант 1. И выходит как-то так вот:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
Program Project1;
 
Uses
  Windows,
  Forms,
  Graphics;
 
Procedure MakeScreenShot(ABitmap: TBitmap);
Const
  CAPTUREBLT = $40000000;
Var
  ScreenDC: HDC;
Begin
ABitmap.PixelFormat := pf24bit;
ABitmap.SetSize(Screen.DesktopWidth, Screen.DesktopHeight);
ScreenDC := GetDC(0);
Try
  BitBlt(ABitmap.Canvas.Handle, 0, 0, Screen.DesktopWidth, Screen.DesktopHeight, ScreenDC, Screen.DesktopLeft, Screen.DesktopTop, SRCCOPY Or CAPTUREBLT);
Finally
  ReleaseDC(0, ScreenDC);
End;
End;
 
Procedure Dither(ABitmap: TBitmap);
Const
  MAX_BYTE     = 255;
  LIM_DECREASE = 30;
  LIM_INCREASE = 30;
Var
  x, y: Integer;
  PPixel: PRGBTriple;
Begin
ABitmap.PixelFormat := pf24bit;
For y := 0 To Pred(ABitmap.Height) Do
  Begin
  PPixel := ABitmap.ScanLine[y];
  For x := 0 To Pred(ABitmap.Width) Do
    Begin
    If (PPixel.rgbtRed > LIM_DECREASE) And (PPixel.rgbtRed < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtRed := PPixel.rgbtRed - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    If (PPixel.rgbtGreen > LIM_DECREASE) And (PPixel.rgbtGreen < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtGreen := PPixel.rgbtGreen - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    If (PPixel.rgbtBlue > LIM_DECREASE) And (PPixel.rgbtBlue < MAX_BYTE - LIM_INCREASE) Then
      PPixel.rgbtBlue := PPixel.rgbtBlue - LIM_DECREASE + Random(LIM_DECREASE + LIM_INCREASE);
    Inc(PPixel);
    End;
  End;
End;
 
Procedure DrawToScreen(ABitmap: TBitmap);
Var
  ScreenDC: HDC;
Begin
ScreenDC := GetDC(0);
Try
  BitBlt(ScreenDC, Screen.DesktopLeft, Screen.DesktopTop, ABitmap.Width, ABitmap.Height, ABitmap.Canvas.Handle, 0, 0, SRCCOPY);
Finally
  ReleaseDC(0, ScreenDC);
End;
End;
 
Procedure MainWork();
Var
  ScreenShot: TBitmap;
  ChangedShot: TBitmap;
Begin
ScreenShot := TBitmap.Create();
ChangedShot := TBitmap.Create();
Try
  MakeScreenShot(ScreenShot);
  While GetAsyncKeyState(VK_ESCAPE) = 0 Do
    Begin
    ChangedShot.Assign(ScreenShot);
    Dither(ChangedShot);
    DrawToScreen(ChangedShot);
    // Sleep(Random(150) + 150);
    End;
Finally
  ChangedShot.Free();
  ScreenShot.Free();
End;
End;
 
Begin
 
Randomize();
MainWork();
 
End.
Добавлено через 1 минуту
А для варианта 2 можно попробовать создать форму, сделать ей:
  • BorderStyle как bsNone
  • Align как alClient
  • AlphaBlendValue как например 90
  • AlphaBlend как True
И при OnPaint просто рисовать на форме шум. По таймеру дёргать Repaint().
1
0 / 0 / 0
Регистрация: 14.07.2019
Сообщений: 15
05.06.2020, 19:15  [ТС] 19
А это значит не верно?
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;
 
type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  bmp: tbitmap;
dc: hdc;
 
implementation
 
{$R *.dfm}
procedure dither(var bitmap:tbitmap);
type
trgb = record
r,g,b: byte;
end;
argb = array[0..1] of trgb;
pargb = ^argb;
var x,y:integer;
p:pargb;
b:tbitmap;
begin
bitmap.pixelformat := pf24bit;
b:=tbitmap.create;
b.assign(bitmap);
for y:=0 to b.height-1 do
begin
p := b.scanline[y];
for x := 0 to b.width-1 do
begin
if (p[x].r>30)and(p[x].r<225) then p[x].r:=p[x].r-30+random(60);
if (p[x].g>30)and(p[x].g<225) then p[x].g:=p[x].g-30+random(60);
if (p[x].b>30)and(p[x].b<225) then p[x].b:=p[x].b-30+random(60);
end;
end;
bitmap.canvas.draw(0,0,b);
end;
begin
while true do begin
dither(bmp);
Sleep(500);
end;
end.
0
884 / 586 / 179
Регистрация: 28.02.2017
Сообщений: 2,359
Записей в блоге: 1
06.06.2020, 02:15 20
  • Ваша переменная bmp нигде не создаётся и равна "пустоте";
  • Зачем вам TForm1 и вообще VCL, если оно вообще не используется?
  • Через вечный цикл со Sleep() уже давным-давно редко что делают;
  • Ваш тип trgb некорректен (не упакован и порядок полей наоборот) да и не нужен: надо было просто брать уже существующий TRGBTriple;
1
06.06.2020, 02:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.06.2020, 02:15
Помогаю со студенческими работами здесь

Видеокарта nvidia geforce gt 220 зернистость
Всем добрий вечер! У меня проблема з видеокертой нвидия geforge gt 220! Видеокарта проработала...

Radeon R9 270X, зернистость и кратковременная тряска изображения
Система такая : i5 760, ram 4gb kingston 1333mhz Купил R9 270X на замену gtx 470 и сразу же...

Монитор или видеоадаптер? искажение изображения (зернистость и зубчатый контур)
Не знаю точно в чём проблема, в мониторе или видеокарте. 3 дня назад обнаружил, что фото вконтакте...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru