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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.12.2014, 21:24   #1
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,152
По умолчанию "выдавливание" области рисунка

В общем, есть PNG-файл. В нем некоторая область на прозрачном фоне. Как съимитировать фотошопный эффект "тиснение", чтоб эта область как бы была выдавлена? Т.е. добавить/убавить яркость пикселей у края, в зависимости от угла этого края...
Изображения
Тип файла: jpg borders2.jpg (22.8 Кб, 83 просмотров)
Smogg вне форума Ответить с цитированием
Старый 06.12.2014, 21:26   #2
Dux
Delphi Master
Форумчанин Подтвердите свой е-майл
 
Аватар для Dux
 
Регистрация: 31.03.2008
Сообщений: 803
По умолчанию

Это Вы хотите программу по "выдавливанию" написать?
Dux вне форума Ответить с цитированием
Старый 06.12.2014, 21:36   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Ну я бы копнул в сторону GDI+ там есть такие возможности
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 06.12.2014, 21:52   #4
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,152
По умолчанию

Цитата:
Сообщение от Dux Посмотреть сообщение
Это Вы хотите программу по "выдавливанию" написать?
Я дурак и не понимаю намеков...
Цитата:
Сообщение от Аватар Посмотреть сообщение
Ну я бы копнул в сторону GDI+ там есть такие возможности
Копания в GDI+ выбрасывали на Direct2D.Effects. Но... Экзамплы требуют Win8.1, а нашедшийся китайский исходник компилируется только в своем первоначальном виде. Любые попытки как-то изменить ни к чему хорошему не приводят. Только очаровательнейшие ошибки: D2DERR_INVALID_GRAPH_CONFIGURATION - A configuration error occurred in the graph..

Т.е. мне нужен алгоритм(

Как мне мерещится, надо делать наподобии bump mapping'a. Т.е. преобразовать в карту высот, а потом расчитывать падение воображаемого света на воображаемую 3Д-поверхность. Где прозрачно, там понятно, что 0-я высота. Где тело объекта - там 1. Но что делать с собственно тем, ради чего собственно все, т.е. с краями?

Последний раз редактировалось Smogg; 06.12.2014 в 21:59.
Smogg вне форума Ответить с цитированием
Старый 11.12.2014, 19:59   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Потратил часик времени и вот что удалось от GDI+ с помощью регионов, градиенов и 40 строк кода добиться. Не совсем то, но близко. Работает как на хрюше, так и 7-ке и без всяких Direct2D
Изображения
Тип файла: jpg Безымянный999.jpg (8.6 Кб, 73 просмотров)
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 11.12.2014, 21:21   #6
Jurijus123
Заблокирован
 
Регистрация: 12.11.2014
Сообщений: 120
По умолчанию

Цитата:
Сообщение от Dux Посмотреть сообщение
Это Вы хотите программу по "выдавливанию" написать?
Я думаю надо назвать тему "по улучшению графики фотографий"
Или "как улучшить качество фотографий"
Jurijus123 вне форума Ответить с цитированием
Старый 12.12.2014, 03:30   #7
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Как-то так
Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, GDIPAPI, GDIPOBJ, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  GPBitmap: TGPBitmap;

implementation

{$R *.dfm}

procedure cut(a: real; var b: byte);
begin
  a := a + b;
  if a > 255 then
    b := 255
  else if a < 0 then
    b := 0
  else
    b := round(a);
end;

procedure TForm1.FormCreate(Sender: TObject);
type
  pix = array [0 .. 1] of byte;
const
  side = 17;
  k = 12 / 17;
  shadow = 0.2;
var
  bmData: TBitmapData;
  p: TGPPoint;
  s: TGPSize;
  i, j: integer;
  b: ^pix;
  g, h: integer;
  sumF: real;
begin
  GPBitmap := TGPBitmap.Create('borders2.png');
  p := MakePoint(0, 0);
  s := MakeSize(integer(GPBitmap.GetWidth), integer(GPBitmap.GetHeight));
  GPBitmap.LockBits(MakeRect(p, s), ImageLockModeRead and ImageLockModeWrite,
    PixelFormat32bppARGB, bmData);
  b := bmData.Scan0;
  for i := 0 to bmData.Height - 1 - 2 * side do
  begin
    for j := 0 to bmData.Width - 1 - 2 * side do
    begin
      // BGRA
      if b[(i + side) * bmData.stride + 4 * (j + side) + 3] = 0 then
        continue;
      sumF := 0;
      for g := i to i + 2 * side do
        for h := j to j + 2 * side do
          if (sqr(abs(i + side - g)) + sqr(abs(j + side - h)) <= sqr(side)) and
            (b[g * bmData.stride + 4 * h + 3] = 0) then
            sumF := sumF + (i + side - g) / side - shadow;
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side)]);
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side) + 1]);
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side) + 2]);
    end;
  end;
  GPBitmap.UnlockBits(bmData);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  GPBitmap.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  graphicsGDIPlus: TGPGraphics;
begin
  graphicsGDIPlus := TGPGraphics.Create(Canvas.Handle);
  graphicsGDIPlus.SetSmoothingMode(4);
  graphicsGDIPlus.DrawImage(GPBitmap, 100, 100);
  graphicsGDIPlus.Free;
end;

end.
1я:
side = 15;
k = 12 / 15;
shadow = 0;
2я:
side = 17;
k = 12 / 17;
shadow = 0.2;
Изображения
Тип файла: png 3d.png (17.9 Кб, 62 просмотров)
Тип файла: png 3d2.png (23.7 Кб, 50 просмотров)
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 12.12.2014 в 14:25.
BDA вне форума Ответить с цитированием
Старый 12.12.2014, 16:24   #8
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,152
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
Потратил часик времени и вот что удалось от GDI+ с помощью регионов, градиенов и 40 строк кода добиться. Не совсем то, но близко. Работает как на хрюше, так и 7-ке и без всяких Direct2D
Даже близко не) Мне надо более-менее правдоподобное:


Т.е. есть исходная картинка, есть маска модулей, есть фон. Исходник режется, перемещается в соответствии с маской, потом накладываются эффекты, полученное рисуется на фоне. Эффекты должны генерироваться только на основе этих трех файлов.

Последний раз редактировалось Smogg; 12.12.2014 в 16:35.
Smogg вне форума Ответить с цитированием
Старый 12.12.2014, 16:35   #9
Smogg
Участник клуба
 
Регистрация: 14.06.2011
Сообщений: 1,152
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Как-то так
Код:
...
  for i := 0 to bmData.Height - 1 - 2 * side do
  begin
    for j := 0 to bmData.Width - 1 - 2 * side do
    begin
      // BGRA
      if b[(i + side) * bmData.stride + 4 * (j + side) + 3] = 0 then
        continue;
      sumF := 0;
      for g := i to i + 2 * side do
        for h := j to j + 2 * side do
          if (sqr(abs(i + side - g)) + sqr(abs(j + side - h)) <= sqr(side)) and
            (b[g * bmData.stride + 4 * h + 3] = 0) then
            sumF := sumF + (i + side - g) / side - shadow;
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side)]);
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side) + 1]);
      cut(k * sumF, b[(i + side) * bmData.stride + 4 * (j + side) + 2]);
    end;
  end;
  GPBitmap.UnlockBits(bmData);
end;
Да, работает как-то, но углы, углы... Ваш подход, через подсчет пустых пикселей внутри круга с центром в текущем пикселе, не дает четких нормалей на углах...

А мне надо, чтоб работало и на круглых и на квадратных картинках.
Smogg вне форума Ответить с цитированием
Старый 13.12.2014, 01:36   #10
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, GDIPAPI, GDIPOBJ, ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  GPBitmap: TGPBitmap;

implementation

{$R *.dfm}

procedure cut(a: real; var b: byte);
begin
  a := a + b;
  if a > 255 then
    b := 255
  else if a < 0 then
    b := 0
  else
    b := round(a);
end;

procedure TForm1.FormCreate(Sender: TObject);
type
  pix = array [0 .. 1] of byte;
const
  dist = 17;
  k = 127;
  shadow = 0.2;
var
  bmData: TBitmapData;
  p: TGPPoint;
  s: TGPSize;
  i, j: integer;
  b: ^pix;
  g, h: integer;
  sumF: real;
  mindist, tmpdist: real;
  pi, pj: integer;
begin
  GPBitmap := TGPBitmap.Create('borders2.png');
  p := MakePoint(0, 0);
  s := MakeSize(integer(GPBitmap.GetWidth), integer(GPBitmap.GetHeight));
  GPBitmap.LockBits(MakeRect(p, s), ImageLockModeRead and ImageLockModeWrite,
    PixelFormat32bppARGB, bmData);
  b := bmData.Scan0;
  for i := 0 to bmData.Height - 1 - 2 * dist do
  begin
    for j := 0 to bmData.Width - 1 - 2 * dist do
    begin
      // BGRA
      if b[(i + dist) * bmData.stride + 4 * (j + dist) + 3] = 0 then
        continue;
      sumF := 0;
      mindist := sqr(2 * dist);
      for g := i to i + 2 * dist do
        for h := j to j + 2 * dist do
          if (b[g * bmData.stride + 4 * h + 3] = 0) then
          begin
            tmpdist := sqr(abs(i + dist - g)) + sqr(abs(j + dist - h));
            if tmpdist < mindist then
            begin
              pi := g;
              // pj := h;
              mindist := tmpdist;
            end;
          end;
      mindist := sqrt(mindist);
      if mindist > dist then
        continue;
      sumF := k * ((i + dist - pi) / dist - shadow);
      cut(sumF, b[(i + dist) * bmData.stride + 4 * (j + dist)]);
      cut(sumF, b[(i + dist) * bmData.stride + 4 * (j + dist) + 1]);
      cut(sumF, b[(i + dist) * bmData.stride + 4 * (j + dist) + 2]);
    end;
  end;
  GPBitmap.UnlockBits(bmData);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  GPBitmap.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  graphicsGDIPlus: TGPGraphics;
begin
  graphicsGDIPlus := TGPGraphics.Create(Canvas.Handle);
  graphicsGDIPlus.SetSmoothingMode(4);
  graphicsGDIPlus.DrawImage(GPBitmap, 100, 100);
  graphicsGDIPlus.Free;
end;

end.
Изображения
Тип файла: png 3d3.png (24.7 Кб, 50 просмотров)
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 13.12.2014 в 01:38.
BDA вне форума Ответить с цитированием
Ответ


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

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Постоянно слетает галочка "автоматически" в "Параметры Excel", "Формулы", "Вычисления в книге" Alexsandrr Microsoft Office Excel 4 19.10.2013 14:22
Создать класс "Фигура", от него наследованием создать 3 класса ("треугольник", "четырехугольник", "окружность") funnyy Помощь студентам 3 17.10.2012 17:40
как можно отключить сообщение "поля раздела выходят за границы области печати. Продолжить?" Dadosh Microsoft Office Word 7 29.07.2012 11:58
Вывести название соответствующей карты вида "шестерка бубен", "дама червей","туз треф" и т.п. воваава Помощь студентам 3 01.12.2011 12:50
при вводе на листе "магазин"- код товара появлялось "описание" товара из "склада" с "продажной ценой" aleksei78 Microsoft Office Excel 13 25.08.2009 12:04