С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi: Графика, звук, видео
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.58/12: Рейтинг темы: голосов - 12, средняя оценка - 4.58
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
1

Визуализация и увеличение. DirectX и прочая графика

26.11.2013, 18:55. Показов 2496. Ответов 25
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Помогите реализовать самым быстрым методом!
Надо открыть файлик с числами (прилагается), визуализировать и увеличить в 2 раза. Проблема кроется как в визуализации, так и в увеличении картинки. Процедура открытия также прилагается. Помогите...
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
unit Interferon;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Menus, Vcl.ExtCtrls, Math, Jpeg,
  Vcl.ExtDlgs, Vcl.StdCtrls, GdiPlus;
 
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
  maxx, maxy: integer;
  ItD: array of array of integer;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.FormCreate(Sender: TObject);
var
  x,y,i,j:integer;
  f:file;
begin
{Это мы открываем файлик}
  AssignFile(f, 'Useful.kfb');
  Reset(f, 1);
  Seek(f, 3);
  BlockRead(f, maxx, 4);
  BlockRead(f, maxy, 4);
  SetLength(ItD, maxx, maxy);
  for i := 0 to maxx - 1 do
    BlockRead(f, ItD[i, 0], maxy * SizeOf(integer));
  CloseFile(f);
  SetLength(Itd, maxx, maxy);
{Теперь ItD открыт. Он длиной 1920х1080.}
 
//Визуализация
 
//Увеличение в 2 раза (до 3840х2160 здесь)
end;
 
end.
И ещё проблема - я не могу увеличить BitMap в GDI+ ибо он требует загрузки из файла
Вложения
Тип файла: zip Project.zip (1.23 Мб, 13 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.11.2013, 18:55
Ответы с готовыми решениями:

Увеличение скорости загрузки из файла obj мешей в Directx
Пробую написать свой класс для загрузки .obj мешей в Directx. Идея в 2 функциях:...

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

Визуализация графика С++ OpenGL
Есть некоторые баги, придётся покопаться в коде, ибо я уже сдал и особого желания выискивать ошибки...

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

25
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
26.11.2013, 23:10  [ТС] 2
Мммммм, так что-то можно сделать? Или всё так безнадежно???
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
27.11.2013, 10:22 3
Цитата Сообщение от SeryZone Посмотреть сообщение
визуализировать и увеличить в 2 раза.
Не понятно.
визуализировать целые числа можно по разному.
увеличить в 2 раза тоже...( хотя тут целые числа наверно без интерполяции ). Просто один пиксель превращается в 4? Зачем?
0
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
27.11.2013, 17:28  [ТС] 4
Да провести визуализацию, потом растянуть в 2 раза - это как StretchDraw, только качественнее.
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
27.11.2013, 18:45 5
Цитата Сообщение от SeryZone Посмотреть сообщение
это как StretchDraw, только качественнее.
То есть нужна линейная интерполяция? А как быть с результатом если значение получится не целое - просто отсечь? Или округлить?

Для быстрой визуализации можно попробовать прикрутить шейдер:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
//FRAGMENT SHADER
  #version 130
  #extension GL_EXT_gpu_shader4 : enable    //defines isampler2D
 
  uniform isampler2D data; // текстура с данными integer(32bit)
  uniform sampler1D palette;// палитра
  smooth in vec2 TexCoord0;
 
  void main()
  {
    int texel = texture2D(data, TexCoord0).x;
    gl_FragColor = texture1D( palette, (float)texel/2147483648.0 + 0.5 );
  }
Добавлено через 6 минут
Загрузка могла выглядеть приблизительно так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
m := TMemoryStream.Create;
m.LoadFromFile( filename );
 
glGenTextures( 1, @FTexData );
glBindTexture( GL_TEXTURE_2D, FTexData );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE32I_EXT, 1920, 1080, 0, GL_LUMINANCE_INTEGER_EXT, GL_INT, m.Memory );
 
m.Free;
0
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
27.11.2013, 20:42  [ТС] 6
Написал, а форум всё взял и не отправил

Так-так, на этом поподробнее)) Как мне связать это с BitMap? Только после интерполяции.
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
28.11.2013, 11:13 7
Цитата Сообщение от SeryZone Посмотреть сообщение
Так-так, на этом поподробнее))
Дело в том что я не знаю как себя поведёт шейдер с целочисленными текстурами(ещё не было опыта их использования). И вы к тому же так и не ответили на мой вопрос:
Цитата Сообщение от snake32 Посмотреть сообщение
А как быть с результатом если значение получится не целое - просто отсечь? Или округлить?
В обычной(не целочисленной) текстуре достаточно настроить фильтрацию(вместо GL_NEAREST, поставить GL_LINEAR)
Delphi
1
2
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
И opengl будет сам интреполировать максимально быстро задействуя GPU. Но это совсем другой тип текстуры. Как поведёт себя integer texture с фильтрацией в режиме GL_LINEAR непонятно. И возможен ли вообще такой режим. Быстрый поиск по интернету не дал мне ответа. Но даже если простой способ не прокатит, то есть ещё как минимум 2 варианта:
- нормализованная текстура, где целочисленные данные загружаются как флоат;
- прямая выборка соседних текстелей(пикселей текструы) в шейдере, где можно реализовать почти любой вид интерполяции).

Цитата Сообщение от SeryZone Посмотреть сообщение
Как мне связать это с BitMap? Только после интерполяции.
Bitmap не нужен. Для реализации растягивания можно прикрутить FrameBuffer с нужным вам разрешением, отрисовать там квад с текстурой и считать данные в память, например в тот же TMemoryStream.

А вообще зачем нужно такое растягивание?
0
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
28.11.2013, 18:02  [ТС] 8
Подождите секундочку... Извините, отлучился просто

Добавлено через 12 минут
Примитив (для примера) выглядит так:

Открыть палитру:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Tcolor = packed record
  r:byte;
  g:byte;
  b:byte;
end;
 
var pal:array[0..4096] of TColor;
 
procedure TForm1.Loadcustompalette4096width1Click(Sender: TObject);
var
  bmp:tbitmap;
  i:integer;
begin
//Палитра обязательно должна быть 4096 пикселов в ширину
  bmp:=TBitMap.Create; bmp.LoadFromFile('Palette.bmp');
  for I := 0 to 4095 do
      begin
        pal[i].r:=GetRValue(bmp.Canvas.Pixels[i,1]);
        pal[i].g:=GetgValue(bmp.Canvas.Pixels[i,1]);
        pal[i].b:=GetbValue(bmp.Canvas.Pixels[i,1]);
      end;
end;
Открыть именно файл:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
var
    i,maxx,maxy:longint;
    f:file;
begin
  AssignFile(f,'Useful.kfb');
  Reset(f, 1); //Открываем файл для чтения/записи с минимальным блоком доступа в 1 байт.
  Seek(f, 3); //Пропускаем первые 3 байта.
  BlockRead(f, MaxX, 4);
  BlockRead(f, MaxY, 4);
  SetLength(IterDat, MaxX, MaxY);
for i := 0 to MaxX-1 do
    BlockRead(f, IterDat[i, 0], MaxY * SizeOf(Integer));
  CloseFile(f);
Визуализация файла:
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
var
  IterDat:array of array of longint;
  MAxx,Maxy:integer;
 
function MinSearch:longint;
var i,j:integer;
    min:longint;
begin
min:=2147483647;
for I := 0 to maxx-1 do
  for j := 0 to maxy-1 do
      if (IterDat[i,j]>0) then
          if (min>IterDat[i,j]) then min:=IterDat[i,j];
      exit(min);
end;
 
function MaxSearch:longint;
var i,j:integer;
    max:longint;
begin
max:=0;
for I := 0 to maxx-1 do
  for j := 0 to maxy-1 do
      if (i<>maxx div 2) and (j<>maxy div 2) then
          if (max<IterDat[i,j]) then max:=IterDat[i,j];
      exit(max);
end;
 
procedure Visualize();
var
    step,ms:real;
    min,max,x,y:longint;
    BitMap:TBitmap;
begin
BitMap:=TBitMap.create; BitMap.SetSize(Maxx,Maxy);
      Min:=MinSearch();
      Max:=MaxSearch();
      Step:=4095/(Max+1-Min);
      index := 0; // cnt := 0;
      ms := min * step;
      for y := 0 to maxy-1 do
        for x := 0 to maxx-1 do
            if (IterDat[x,y]>=max) then
              begin
                 BitMap.canvas.Pixels[x,y]:=clBlack;
              end else
            if (IterDat[x,y]>=0) then
              begin
                    BitMap.canvas.pixels[x,y]:=pal[round((IterDat[x,y])*step-ms) mod 4095];
              end;
end;
Добавлено через 12 минут
Далее Надо провести растяжение того BitMap до нужных мне размеров.
А тот ваш вопрос не очень понятен.
Я написал так, чисто символически визуализацию - pixels[] я не юзаю уже давно. Правда - чтение палитры...
Я вcе целые округляю Round().
Задача вот в чём:
Delphi
1
2
3
4
5
6
7
8
9
10
ОткрытьПалитру()
zom:=exp(ln(2)/300);
for i:=1 to 300 do
begin
Открыть();
Визуализировать();
Zoom:=exp(ln(zom),i-1);
Растянуть(round(maxx*zoom),round(maxy*zoom));
СохранитьВJPEG(Format('%d',[i]));
end;
Добавлено через 7 минут
Оххххххх!!! Открыть() перед циклом.

Да-да, визуализировать по-новой в каждом цикле. Потому что походу Значения Min и Max будут меняться!
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
28.11.2013, 20:21 9
Цитата Сообщение от SeryZone Посмотреть сообщение
Растянуть(round(maxx*zoom),round(maxy*zoom));
Что-то мне лень считать. Какое максимальное разрешение получается?

Добавлено через 6 минут
Цитата Сообщение от SeryZone Посмотреть сообщение
Zoom:=exp(ln(zom),i-1);
exp с двумя параметрами?

Добавлено через 1 минуту
Ещё не понятно что делать с отрицательными значениям? В вашем коде они игнорируются.

Добавлено через 1 минуту
при поиске максимального значения почему игнорится центральный пиксель?
0
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
28.11.2013, 23:21  [ТС] 10
О, Боже!!! Я хотел написать
Delphi
1
exp(ln(zoom)*(i-1))
Это ж возведение в степень - типо наш зум. Да, чтобы по центру рисовать, надо брать отриц. значения. Но для битмап Draw() работает с отрицательными безотказно.

Добавлено через 1 минуту
Цитата Сообщение от snake32 Посмотреть сообщение
при поиске максимального значения почему игнорится центральный пиксель?
Да, потому что он, падла всегда огромного значения и в него уйдёт весь цвет!!!
Например, он значений так 15 000 000
А все остальные где-то 20 000-30 000. Вот и в максимум всё уйдет...
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
02.12.2013, 02:50 11
SeryZone, вообщем поэксперементировал я с вашим файлом... как я понял на прямую считывать как картинку файл Useful.kfb нельзя. Должно быть что-то ещё... так как явно идёт какой-то сдвиг пикселей( см 1 картинку )
Однако есть интересный эффект( см картинку 2 ). Если сжать по вертикали с 1080 до 120 пикселей то получается что шейдер берёт только каждый 9 пиксель - остальные пропускает и получается более-менее адекватная картинка. Вообщем думаю должны где-то лежать ещё правила как правильно считывать данные в картинку.
Миниатюры
Визуализация и увеличение. DirectX и прочая графика   Визуализация и увеличение. DirectX и прочая графика  
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
02.12.2013, 02:52 12
Кстати что это за данные?
0
angstrom
02.12.2013, 03:17 13
На самом деле это обычный RAW файл и размерность его не 1920х1080, а 1080х1920. Прекрасно смотрится через IrfanView.
angstrom
02.12.2013, 03:20 14
Его вид.
Изображения
 
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
02.12.2013, 17:54  [ТС] 15
Я не согласен с этим... И вообще, странно... Сейчас, разберусь. И кстати, вот реальная визуализация:
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
procedure TForm1.f1Click(Sender: TObject);
var
    x,y,i:longint;
    f:file;
begin
  OpenMap.Execute();
  {-------------------------}
  AssignFile(f,'Useful.kfb');
  Reset(f, 1); //Открываем файл для чтения/записи с минимальным блоком доступа в 1 байт.
  Seek(f, 3); //Пропускаем первые 3 байта.
  {Читаем MaxX и MaxY}
  BlockRead(f, MaxX, 4);
  BlockRead(f, MaxY, 4);
  //Выделяем память для массива.
  SetLength(IterDat, MaxX, MaxY);
  //Читаем данные в массив.
for i := 0 to MaxX-1 do
    BlockRead(f, IterDat[i, 0], MaxY * SizeOf(Integer));
  //Закрываем файл.
  CloseFile(f);
  {-------------------------}
  Form1.Image1.Width:=Maxx; Form1.Image1.Height:=MaxY;
    Form1.Image1.Picture := nil; // <--- Вот тут
  Form1.Image1.Picture.Bitmap.SetSize(Form1.Image1.Width, Form1.Image1.Height);
  MyBMInfo.bmiHeader.biSize := SizeOf(MyBMInfo.bmiHeader);
  res := GetDIBits(Form1.Image1.Canvas.Handle, Form1.Image1.Picture.Bitmap.Handle, 0, MyBMInfo.bmiHeader.biHeight, nil, MyBMInfo, DIB_RGB_COLORS);
  if res = 0 then ShowMessage('error first getdibits');
  SetLength(buffer, MyBMInfo.bmiHeader.biSizeImage{div SizeOf(RGBTRIPLE)});
  MyBMInfo.bmiHeader.biBitCount := 32;
  MyBMInfo.bmiHeader.biCompression := BI_RGB;
  MyBMInfo.bmiHeader.biHeight := Abs(MyBMInfo.bmiHeader.biHeight);
 
  res := GetDIBits(Form1.Image1.Canvas.Handle, Form1.Image1.Picture.Bitmap.Handle, 0, MyBMInfo.bmiHeader.biHeight, Buffer, MyBMInfo, DIB_RGB_COLORS);
 
  Visualize;
end;
 
procedure Visualize;
var
    step,ms:real;
    min,max,index,ColorIndex,x,y:longint;
begin
  Form1.Image1.Canvas.Brush.Color:=clBlack;
  form1.Image1.Canvas.Rectangle(0,0,form1.Image1.width,form1.Image1.Height);
  case COLORMETHOD of
  1:begin
      Min:=MinSearch();
      Max:=MaxSearch();
      Step:=4095/(Max+1-Min);
      index := 0; // cnt := 0;
      ms := min * step;
      for y := 0 to maxy-1 do
        for x := 0 to maxx-1 do
          begin
            if (IterDat[x,y]>=max) then
              begin
                buffer[index] := 0;           // red
                buffer[index+1] := 0;         // green
                buffer[index+2] := 0;         // blue
              end else
            if (IterDat[x,y]>0) then
              begin
                ColorIndex := round((IterDat[x,y])*step-ms) mod 4096;
                buffer[index] := pal[ColorIndex].B;     // red
                buffer[index+1] := pal[ColorIndex].G;   // green
                buffer[index+2] := pal[ColorIndex].R;   // blue
              end;
            inc(index, 4)
          end;
    end;
    res := SetDIBits(Form1.Image1.Canvas.Handle, Form1.Image1.Picture.Bitmap.Handle, 0,
      MyBMInfo.bmiHeader.biHeight, Buffer, MyBMInfo, DIB_RGB_COLORS);
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
02.12.2013, 18:44 16
Цитата Сообщение от SeryZone Посмотреть сообщение
Я не согласен с этим...
С чем именно?
Цитата Сообщение от SeryZone Посмотреть сообщение
И кстати, вот реальная визуализация:
Где результат реальной визуализации?
0
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
02.12.2013, 20:45  [ТС] 17
Ох... Простите... Голова просто болит...
Вот тут всё как надо. Главное - сверхбыстро интерполировать.

GDI+ не хочет просто так интерполировать (хотя такой быстрый и удобный) - он обязательно должен загружать изображение - а у меня BitMap. В общем, вот...
Миниатюры
Визуализация и увеличение. DirectX и прочая графика  
Вложения
Тип файла: zip Project.zip (1.86 Мб, 6 просмотров)
0
angstrom
02.12.2013, 22:25 18
Это неверный рисунок. Если посмотреть файл, то видно, что байты идут в обратном порядке. Отсюда и сине-фиолетовый цвет. Хотя, я может быть не прав, вдруг рисунок с прозрачностью. ТС скажи как верно. Я написал небольшой пример для быстрой конвертации, ответ только за ТС о правильной раскладке цвета.
56 / 28 / 18
Регистрация: 09.03.2012
Сообщений: 726
Записей в блоге: 1
02.12.2013, 22:30  [ТС] 19
angstrom, Исходничек в архиве посмотрите - там ясно видно и чтение и визуализация.
0
3460 / 1648 / 236
Регистрация: 26.02.2009
Сообщений: 8,050
Записей в блоге: 5
02.12.2013, 22:35 20
SeryZone, а зачем вам увеличение? Почему нельзя увеличить готовую картинку обычным редактором?
0
02.12.2013, 22:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.12.2013, 22:35
Помогаю со студенческими работами здесь

Визуализация числового массива (создание графика)
У меня есть числовой массив - числа с плавающей точкой - нет ли какой-нибудь функции или библиотеки...

Qt графика на DirectX 11 ?
Ну собственно два подвопроса: 1. Можно ли под Windows7 рисовать 3д графику на кьюте через директХ...

C++ Графика (MS DirectX SDK)
На сайте я прочитал, что MS DirectX SDK - это как доп. утилита для С++. Хотел спросить, ее ставят...

Увеличение размера графика в окне figure
строю одновременно 25 графиков - это сигнал ЭЭГ от 25 электродов. Матлаб выводит их как линии....


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

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