powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите сделать правильный scaler
8 сообщений из 8, страница 1 из 1
Помогите сделать правильный scaler
    #39895860
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Смысл - картинка увеличивается в нецелое количество раз, а пиксели сглаживаются только по границе. Например, если увеличение в 3,5 раз, то будет пиксель размером 3,5x3,5 (3px залито сплошным цветом, а 0,5 попадает на 4-й пиксель, и он, соответственно, сглажен цветом 3 и 4 пикселя).
Если сложно представить, то сделайте в фотошопе сначала scale до 3500% методом nearest neighbour, а затем уменьшите до 10% методом bilinear) - это будет выглядеть как scale на 350% моим методом.

Код: pascal
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.
procedure ExplodeColor(const color1:tcolor;var r,g,b:Byte);
var col:longword;
begin
      col:=ColorToRGB(color1);
      r:=Byte(col);
      g:=Byte(col shr 8);
      b:=Byte(col shr 16);
end;

function AddColor(const color1,color2:tcolor):tcolor;
var r1,g1,b1:byte;
    r2,g2,b2:byte;
    rr,gg,bb:byte;
begin
ExplodeColor(color1,r1,g1,b1);
ExplodeColor(color2,r2,g2,b2);
if r1+r2<=255 then rr:=r1+r2 else rr:=255;
if g1+g2<=255 then gg:=g1+g2 else gg:=255;
if b1+b2<=255 then bb:=b1+b2 else bb:=255;
Result:=RGB(rr,gg,bb);
end;

procedure TForm1.Button1Click(Sender: TObject);
var x,y:integer;
    scale:double;
    xx,yy:integer;
    src_rr,src_gg,src_bb:byte;
    dst_rr,dst_gg,dst_bb:byte;
    add_percent:double;
    tmp_val:integer;
    pixel_left:double;
    pixel_top:double;
    pixel_right:double;
    pixel_bottom:double;
    pixel_left_plus:integer;
    pixel_top_plus:integer;
    pixel_right_plus:integer;
    pixel_bottom_plus:integer;
    pixel_mult_left,pixel_mult_top:double;
    pixel_mult_right,pixel_mult_bottom:double;
begin
scale:=3.5;
image1.Picture.LoadFromFile('Untitled-3.bmp');

Image2.Canvas.Create;
Image2.Picture.Graphic.Width:=round(image1.picture.width*scale);
Image2.Picture.Graphic.Height:=round(image1.picture.Height*scale);
image2.Canvas.Brush.Color:=clBlack;
image2.Canvas.FillRect(rect(0,0,image2.Picture.Graphic.Width,image2.Picture.Graphic.Height));
image2.Canvas.Brush.Color:=clWhite;
for y:=0 to Image1.Picture.Height-1 do
  begin
  for x:=0 to Image1.Picture.Width-1 do
    begin
    pixel_left:=x*scale;
    pixel_top:=y*scale;
    pixel_right:=(x+1)*scale;
    pixel_bottom:=(y+1)*scale;
    if frac(pixel_left)<1e-10 then begin pixel_left_plus:=0; pixel_mult_left:=1; end else begin pixel_left_plus:=0; pixel_mult_left:=1-frac(pixel_left); end;
    if frac(pixel_top)<1e-10 then begin pixel_top_plus:=0; pixel_mult_top:=1; end else begin pixel_top_plus:=0; pixel_mult_top:=1-frac(pixel_top); end;
    if frac(pixel_right)<1e-10 then begin pixel_right_plus:=-1; pixel_mult_right:=1; end else begin pixel_right_plus:=0; pixel_mult_right:=frac(pixel_right); end;
    if frac(pixel_bottom)<1e-10 then begin pixel_bottom_plus:=-1; pixel_mult_bottom:=1; end else begin pixel_bottom_plus:=0; pixel_mult_bottom:=frac(pixel_bottom); end;
    for xx:=trunc(pixel_left)+pixel_left_plus to trunc(pixel_right)+pixel_right_plus do
      begin
      for yy:=trunc(pixel_top)+pixel_top_plus to trunc(pixel_bottom)+pixel_bottom_plus do
        begin
        ExplodeColor(Image1.Canvas.Pixels[x,y],src_rr,src_gg,src_bb);
        ExplodeColor(Image2.Canvas.Pixels[xx,yy],dst_rr,dst_gg,dst_bb);
        add_percent:=1;
        if (xx=trunc(pixel_left)+pixel_left_plus) and (yy=trunc(pixel_top)+pixel_top_plus) then add_percent:=((pixel_mult_left+pixel_mult_top)/2)/2;
        if (xx=trunc(pixel_left)+pixel_left_plus) and (yy>trunc(pixel_top)+pixel_top_plus) and (yy<trunc(pixel_bottom)+pixel_bottom_plus) then add_percent:=pixel_mult_left;
        if (xx=trunc(pixel_left)+pixel_left_plus) and (yy=trunc(pixel_bottom)+pixel_bottom_plus) then add_percent:=((pixel_mult_left+pixel_mult_bottom)/2)/2;

        if (xx=trunc(pixel_right)+pixel_right_plus) and (yy=trunc(pixel_top)+pixel_top_plus) then add_percent:=((pixel_mult_right+pixel_mult_top)/2)/2;
        if (xx=trunc(pixel_right)+pixel_right_plus) and (yy>trunc(pixel_top)+pixel_top_plus) and (yy<trunc(pixel_bottom)+pixel_bottom_plus) then add_percent:=pixel_mult_right;
        if (xx=trunc(pixel_right)+pixel_right_plus) and (yy=trunc(pixel_bottom)+pixel_bottom_plus) then add_percent:=((pixel_mult_right+pixel_mult_bottom)/2)/2;

        if (yy=trunc(pixel_top)+pixel_top_plus) and (xx>trunc(pixel_left)+pixel_left_plus) and (xx<trunc(pixel_right)+pixel_right_plus) then add_percent:=pixel_mult_top;
        if (yy=trunc(pixel_bottom)+pixel_bottom_plus) and (xx>trunc(pixel_left)+pixel_left_plus) and (xx<trunc(pixel_right)+pixel_right_plus) then add_percent:=pixel_mult_bottom;

        tmp_val:=Round(dst_rr+src_rr*add_percent);
        if tmp_val<=255 then dst_rr:=tmp_val else dst_rr:=255;
        tmp_val:=Round(dst_gg+src_gg*add_percent);
        if tmp_val<=255 then dst_gg:=tmp_val else dst_gg:=255;
        tmp_val:=Round(dst_bb+src_bb*add_percent);
        if tmp_val<=255 then dst_bb:=tmp_val else dst_bb:=255;
        Image2.Canvas.Pixels[xx,yy]:=rgb(dst_rr,dst_gg,dst_bb);
        end;
      end;
    end;
  end;
end;




Этот мой код делает картинку с артефактами, а надо без артефактов.
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39895882
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так пойдет?
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39895966
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, но хотелось бы моим методом.
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39896092
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
registered
Спасибо, но хотелось бы моим методом.

а почему ?
нужен результат, или пое... покодить ?
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39896131
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Результат. Там он отличается (более размыт), где-то граница размытия 2px, а не 1.
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39896244
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

и в чем проблема?

для каждого нового пикселя просто считаешь,
сколько процентов от него попадает на каждый старый,
и используешь эти веса для смешения старых цветов
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39896430
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered
Результат. Там он отличается (более размыт), где-то граница размытия 2px, а не 1.
Тогда используй нормальную библиотеку с выбором алгоритма ресайза, а не этот тормозной лютый ужас.
...
Рейтинг: 0 / 0
Помогите сделать правильный scaler
    #39896471
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, если сделать scale=3.4, то гораздо меньше "дырок", и не работает только на границах, когда дробная часть от x и y *scale равна нулю, что-ли так.
Соответственно, если сделать 3.33, то вообще практически нет артефактов.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Помогите сделать правильный scaler
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]