Конференция "Media" » Аналоговые часы
 
  • исследователь © (20.08.07 23:43) [60]
    Я по глупости своей пишу

    tm1.LoadFromFile('back.bmp');
    // tm1 - это перем. типа TBitmap
    tm1.width:=tm1.width*3;
    tm1.height:=tm1.height*3;
    tm1.stretchdraw(rect(0,0,tm1.width,tm1.height), tm1);

    но это бред, не работает.
  • antonn © (20.08.07 23:44) [61]
    через CopyRect()
    там в примере есть код, который на определенной области рисует сглаженные линии. Создается временный битмап, размерами в 3 раза больше нужной области.
    var _Bitmap:Tbitmap;
    begin
    _Bitmap:=TBitmap.Create;
     try

    BitmapPrepare(_Bitmap,Image1.Picture.Bitmap.Canvas,rect(10,10,200,200)); //берем прямоугольник, в котором будет рисовать, и увеличия ваего в 3 раза копируем на временный битмап

    //дальше работаем с _Bitmap.canvas как нам надо

    _Bitmap.Canvas.Pen.Width:=3; //устанавливаем толщину в 3 раз больше

    _Bitmap.Canvas.Ellipse(20*3,20*3,80*3,80*3);
    _Bitmap.Canvas.MoveTo(50*3-1,60*3-1); //все координаты в 3 раза больше (хотя для лучшего эффекта, можно отнять еденицу - будет более смазано и качественно, главное не переборщить:))
    _Bitmap.Canvas.LineTo(5*3,15*3);

    _Bitmap.Canvas.Brush.Style:=bsclear;
    _Bitmap.canvas.Font.Size:=_Bitmap.canvas.Font.Size*3; //тут правда косячно с размером...
    _Bitmap.canvas.TextOut(2,2,'Im - super :)');

    Alias(_Bitmap,Image1.Picture.Bitmap.Canvas,rect(10,10,200,200)); //вывод временного битмапа с уменьшением на "лицевой" битмап

     finally
    _Bitmap.Free;
     end;
    end;

  • исследователь © (20.08.07 23:58) [62]
    В общем, ничего не выходит. Процедура делания скина вырезана для уменьшения поста.

    unit uMain;

    interface

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

    type
     TfrmMain = class(TForm)
       timer1: TTimer;
       Image1: TImage;
       procedure FormCreate(Sender: TObject);
       procedure timer1Timer(Sender: TObject);
     private
       { Private declarations }
       procedure DrawArrows(c1, c2, c3 : TColor);
     public
       { Public declarations }
     end;

    var
     frmMain: TfrmMain;
     CX, CY, HArrow, MArrow, SArrow : Integer;
     HA, MA, SA : Real;
     H, M, S, MS : word;
     tm1, tm2, tm3 : TBitmap;
    implementation

    {$R *.dfm}

    procedure Alias(var SourceBitmap:TBitmap; CanvasOut:TCanvas; _R:TRect);
    const
     MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
    type
     PRGBArray = ^TRGBArray;
     TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
    var
     x,y,cx,cy,cxi,totr,totg,totb,i: Integer;
     Row1,Row2,Row3,DestRow: PRGBArray;
    begin
     for Y:=0 to (SourceBitmap.Height div 3)-1 do begin
       cy := y*3;
       DestRow := SourceBitmap.ScanLine[y];
       Row1:=SourceBitmap.ScanLine[cy];
       Row2:=SourceBitmap.ScanLine[cy+1];
       Row3:=SourceBitmap.ScanLine[cy+2];
      for x := 0 to (SourceBitmap.Width div 3)-1 do begin
         cx := x*3;
         totr := 0; totg := 0; totb := 0;
           for i := 0 to 2 do begin
             cxi := cx + i;
             totr := totr + Row1[cxi].rgbtRed + Row2[cxi].rgbtRed + Row3[cxi].rgbtRed;
             totg := totg + Row1[cxi].rgbtGreen + Row2[cxi].rgbtGreen + Row3[cxi].rgbtGreen;
             totb := totb + Row1[cxi].rgbtBlue + Row2[cxi].rgbtBlue + Row3[cxi].rgbtBlue;
           end;
           DestRow[x].rgbtRed := totr div 9;
           DestRow[x].rgbtGreen := totg div 9;
           DestRow[x].rgbtBlue := totb div 9;
       end;
      end;
     CanvasOut.CopyRect(_R,SourceBitmap.Canvas,rect(0,0,SourceBitmap.Width div 3,SourceBitmap.Height div 3));
    end;

    procedure BitmapPrepare(var SourceBitmap:Tbitmap; CanvasOut:TCanvas; _R:TRect);
    begin
    SourceBitmap.PixelFormat:=pf24bit;
    SourceBitmap.Width:=(_r.Right-_r.Left)*3;
    SourceBitmap.Height:=(_r.Bottom-_r.Top)*3;
    SourceBitmap.Canvas.CopyRect(rect(0,0,SourceBitmap.Width,SourceBitmap.Height),Ca nvasOut,_R);
    end;

    procedure TfrmMain.DrawArrows(c1, c2, c3: TColor);
    var r : LongBool;
    begin
    with tm3.Canvas do
    begin
     SetBkMode(Handle, Transparent);
     Pen.Color := clBlack;
     Font.Name := 'Arial';
     Font.Style := [fsBold];
     TextOut(tm2.Width-60, tm2.Height div 2-8, Copy(DateToStr(Now),1,2));
     Pen.Color := c1;
     MoveTo(CX, CY);
     Pen.Width := 4;
     LineTo(CX+Round(HArrow  * 3 *  sin(HA)), CY-Round(HArrow * 3 * cos(HA)));
     MoveTo(CX, CY);
     Pen.Color := c2;
     Pen.Width := 3;
     LineTo(CX+Round(MArrow  * 3 * sin(MA)), CY-Round(MArrow  * 3 * cos(MA)));
     Pen.Color := c3;
     Pen.Width := 2;
     MoveTo(CX, CY);
     LineTo(CX+Round(SArrow  * 3 *  sin(SA)), CY-Round(SArrow * 3 *cos(SA)));
    end;
    image1.Picture.Assign(tm3);
    end;

    procedure TfrmMain.FormCreate(Sender: TObject);
    begin
    HArrow := CX - 30;
    MArrow := CX - 50;
    SArrow := CX - 70;
    tm3 := TBitmap.Create;
    tm1 := TBitmap.Create;
    tm2 := TBitmap.Create;
    tm1.LoadFromFile('background.bmp');
    tm2.Height:=tm1.Height;
    tm2.Width := tm1.Width;
    BitmapPrepare(tm3, tm1.Canvas, rect(0,0,tm1.Width,tm1.Height));
    CX := tm1.Width div 2;
    CY := tm1.Height div 2;
    timer1timer(sender);
    // frmMain.clientWidth := tm1.Width;
    //frmMain.clientHeight := tm1.Height;
    // SetWindowRgn(Self.Handle, BitmapToRgn(tm1), True);
    end;

    procedure TfrmMain.timer1Timer(Sender: TObject);
    begin
    DecodeTime(Time, H, M, S, MS);
    HA := (H/6 + M/360 + S/21600)*PI + PI;
    MA := (M/30 + S/1800)*PI + PI;
    SA := (S/30 + MS/30000)*PI + PI;
    BitBlt(tm3.Canvas.Handle,
           0,0,
           tm3.Width,tm3.Height,
           tm1.Canvas.Handle, 0,0, SRCCOPY);
    DrawArrows(clRed, clGreen, clBlue);
    Alias(tm3, tm2.Canvas, Rect(0,0, tm3.Width,tm3.Height));
    BitBlt(Canvas.Handle, 0,0,Width,Height, tm2.Canvas.Handle,0,0, SRCCOPY);
    end;

    end.

  • исследователь © (21.08.07 00:02) [63]
    Что я делаю:

    1. в форм крит

    Гружу в tm1 циферблат
    Увеличиваю в три раза в tm3
    для проверки кидаю в TImage, бред там
    по тику таймера считаю углы и закрашиваю все циферблатом (походу тут баг, т.к. размеры не совпадают)
    рисую стрелки
    делаю АА
    вывожу на форму
  • antonn © (21.08.07 00:27) [64]
    BitmapPrepare(tm3, tm1.Canvas, rect(0,0,tm1.Width,tm1.Height));
    подставить вместо
    BitBlt(tm3.Canvas.Handle,
          0,0,
          tm3.Width,tm3.Height,
          tm1.Canvas.Handle, 0,0, SRCCOPY);

    image1.Picture.Assign(tm3); из DrawArrows убрать

    Alias(tm3, tm2.Canvas, Rect(0,0, tm3.Width,tm3.Height)); - размеры выводимой области равны изначальной - rect(0,0,tm1.Width,tm1.Height)
  • исследователь © (21.08.07 00:34) [65]
    Спасибо, но стрелки теперь не по центру рисуются.
  • исследователь © (21.08.07 00:40) [66]
    Понял, просто Cx и CY тоже ж на 3 надо умножать
  • исследователь © (21.08.07 00:40) [67]
    Понял, просто Cx и CY тоже ж на 3 надо умножать
  • antonn © (21.08.07 00:43) [68]
    для красоты можно умножить на 3 и прибавить 1, так они будут лучше смазаны.
    кстати, толщину линии тоже на 3 нужно умножить:)
  • исследователь © (21.08.07 00:56) [69]
    Я уже должен Вам отвесить огромный поклон. Но можно еще последнийх три вопроса: на основе чего работает алгоритм AA? Как я понял, берется цветовой массив каждой из строк картинки, затем в ней анализируются по три смежных индекса массива (как я понял, идут тройки: R1G1B1R2G2B2... верно?), это происходит в каждой из смежныхъ строк, затем идет замена в одной определенной строчке (ЧТО это за строка, объясните! Почему именно она?), цветовых составляющих, и это что-тьо дает. Это втрой вопрос - что? И третий - верно ли я понял? :)
  • antonn © (21.08.07 01:07) [70]
    берется изображение, увеличивается в три раза "квадратным способом", т.е. без всяких сглаживаний, просто "увеличиваются" пиксели в три раза.
    при вызове Alias просто берем 9 пикселей (в квадрате 3*3) и для каждого канала считаем среднее значение, и это значение вписываем в результирующий битмап. Для фона ничего не изменится, потому как эти 9 пикселей будут одинаковы.

    Про строчку не понял, где какая строка смущает? :)
  • исследователь © (21.08.07 01:13) [71]
    Так с того, что мы вписали среднее значение, как я и сказал, что случилось?

    Смущает строчка DestRow, ведь это строки (в битмапе на 12 строк) номер 0, 1, 2 и 3. Почему только они?
  • antonn © (21.08.07 01:32) [72]

    > Так с того, что мы вписали среднее значение, как я и сказал,
    >  что случилось?

    для фона - ничего, а вот для тех частей, где нарисована стрелка - там будет темнее (тем темнее, чем больше там видно стрелки).
    Допустим фон, был один пиксель, его размножили:
    0 0 0
    0 0 0
    0 0 0


    если его теперь сложить из этих 9 пикселей, то среднее будет 0, как и изначальное.

    нарисовали стрелку под углом, она "слегка" задела несколько пикселей
    1 1 0
    1 0 0
    0 0 0


    теперь сренее будет не 0, а с "примесью" стрелки.
    вообще для эксперимента можно натыкать в код типа такого
    botmap.savetromfile('C:\1.bmp'); и в панте в приближении рассмореть эти пиксели:)

    DestRow - это строка выходного битмапа, в него загоняется среднее значение канала из 9 пикселей. Все равно не понял, в чем вопрос:)
  • исследователь © (21.08.07 01:40) [73]
    Почему мы в DestRow загоняем ср. знач. пикселей, ведь на 12 строк destrow - Это всего четыре строки?
  • antonn © (21.08.07 01:58) [74]
    DestRow := SourceBitmap.ScanLine[y]; - это на каждую строку выходного битмапа, т.е. равно высоте битмапа.

    просто получается так. На этом увеличенном битмапе в левом верхнем углу выходит сжатое изображение, которое копируется на канву (можно сохранить битмап в файл перед CanvasOut.CopyRect() и посмотреть, на фоне большой копии в углу будет сжатое со сглаживаением)
  • исследователь © (21.08.07 02:11) [75]
    Хм, не на каждую - у идет от 0 до (высота div 3) -1
  • исследователь © (21.08.07 03:04) [76]
    Я ошибаюсь? Вы поправьте меня, если я не прав.
  • @!!ex © (21.08.07 09:40) [77]
    > [54] antonn ©   (20.08.07 23:15)

    С лупой смотрел, особой разницы не заметил.
    Но при ближайшем рассмотрении действительно зубцы есть.
    Будет время сегодня вечером чуть модифицирую, чтобы не было зубцов.
    ИМХо применять альясинг ко всей картинке, при рисовании одной линии - слегка расточительно....
  • Сергей М. © (21.08.07 10:21) [78]

    > исследователь


    Скин-механизмы работают совершенно по-иному.

    То, о чем ты ведешь речь, к скинам имеет самое отдаленное отношение и сводится просто к смене/масштабированию статической фоновой картинки.
  • исследователь © (21.08.07 11:03) [79]

    > Сергей М. ©   (21.08.07 10:21) [78]

    Ты хоть номер поста ставь, я не понял, о чем ты.
 
Конференция "Media" » Аналоговые часы
Есть новые Нет новых   [134431   +10][b:0.001][p:0.004]