Recent

Author Topic: Centering Thumbs, perhaps more math than graphics help please  (Read 244 times)

zxandris

  • Full Member
  • ***
  • Posts: 170
Centering Thumbs, perhaps more math than graphics help please
« on: February 21, 2025, 05:32:29 am »
I've got this little routine :-

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.actGenerateContactSheetExecute(Sender: TObject);
  2. var
  3.    frm : TfrmDLGContactSheet;
  4.    lst : TStringList;
  5.    a : Integer;
  6.    pgWidth, pgHeight, thWidth, thHeight, cellWidth, cellHeight : Integer;
  7.    pgCount, pgTotal, pgCellTotal : Integer;
  8.    bgraThumb, bgraPage, bgraCurrent : TBgraBitmap;
  9.    x, y : Integer;
  10.    sze : TSize;
  11.    txt : String;
  12.    ps, os, ns : TPoint;
  13.    rct : TRect;
  14.    intMargin, intColCount, intRowCount : Integer;
  15. begin
  16.      frm := TfrmDLGContactSheet.create(self);
  17.      try
  18.         lst := TStringList.create;
  19.         try
  20.             GetCurrentList(lst);
  21.             if lst.count-1=-1 then lst.add(GetCurrentImageFilename);
  22.             try
  23.                for a := 0 to lst.count - 1 do frm.AddToFiles(lst[a]);
  24.             except
  25.                   //
  26.             end;
  27.         finally
  28.                lst.free;
  29.         end;
  30.  
  31.         // Show and action dialog
  32.         if frm.ShowModal = mrOK then
  33.         begin
  34.              // Go for it
  35.              pgWidth := frm.seSheetWidth.value;
  36.              pgHeight := frm.seSheetHeight.value;
  37.              thWidth := frm.seThumbWidth.value;
  38.              thHeight := frm.seThumbHeight.value;
  39.              cellWidth := thWidth + (frm.seThumbMargin.value * 2);
  40.              cellHeight := thHeight + (frm.seThumbMargin.value * 2);
  41.              pgCellTotal := ((pgWidth - frm.seSheet_Margin.value) div cellWidth) + ((pgHeight - frm.seSheet_Margin.value) div cellHeight);
  42.              pgTotal := ((frm.lvFiles.items.count - 1) div pgCellTotal);
  43.  
  44.              intColCount := pgWidth;
  45.              intColCount := intColCount - (frm.seSheet_Margin.value);
  46.              intColCount := round(intColCount / cellWidth);
  47. //             if intColCount mod CellWidth>0 then intColCount := intColCount+ 1;
  48.  
  49.              intRowCount := pgHeight;
  50.              intRowCount := intRowCount - (frm.seSheet_Margin.value * 2);
  51.              intRowCount := round(intRowCount / cellHeight);
  52.  
  53.              intMargin := pgWidth;
  54.              intMargin := intMargin - (frm.seSheet_Margin.value * 2);
  55.              intMargin := intMargin - (cellWidth * intColCount);
  56.              if intMargin<frm.seSheet_Margin.value then intMargin := frm.seSheet_Margin.value;
  57.  
  58.  
  59.              // Duh!  I cannot get the centering to work so for now
  60. //             intMargin := frm.seSheet_Margin.value;
  61.  
  62.              pbar.maxValue := frm.lvFiles.items.count - 1;
  63.              // Start new page here
  64.              bgraPage := TBgraBitmap.create(pgWidth, pgHeight);
  65.              try
  66.                 x := intMargin;
  67.                 y := frm.seSheet_Margin.value;
  68.                 pgCount := 0;
  69.  
  70.                 // Prepare First Page
  71.  
  72.                 // Draw BG
  73.                 bgraPage.FillRect(0, 0, pgWidth, pgHeight, frm.cbSheetBackground.ButtonColor);
  74.  
  75.                 // Page Header
  76.                 bgraPage.FontName := frm.cboFont.Text;
  77.                 bgraPage.FontHeight := 12;
  78.                 txt := frm.txtHeader.text;
  79.                 txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  80.                 txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  81.                 txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  82.                 txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  83.                 txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  84.                 txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  85.  
  86.                 // Get Text Size
  87.                 sze := bgraPage.TextSize(txt);
  88.                 // Output Page Header (Centered)
  89.                 if frm.chkShowHeader.checked then
  90.                    bgraPage.TextOut((pgWidth div 2) - (sze.width div 2), 0, txt, frm.cbTextColor.ButtonColor);
  91.  
  92.                 for a := 0 to frm.lvFiles.items.count - 1 do
  93.                 begin
  94.                      pbar.value := a;
  95.                      application.ProcessMessages;
  96.                      bgraCurrent := TBgraBitmap.create;
  97.                      try
  98.                         if fileExists(frm.lvFiles.items.item[a].caption) then
  99.                         begin
  100.                             LoadToBgra(frm.lvFiles.items.item[a].caption, bgraCurrent);
  101.                             BgraCurrent.ResampleFilter := rfBestQuality;
  102.                             os.x := BgraCurrent.width;
  103.                             os.y := BgraCurrent.Height;
  104.                             ns.x := thWidth;
  105.                             ns.y := thHeight;
  106.                             ps := ProportionalSize(os, ns);
  107.                             bgraThumb := TBgraBitmap.create;
  108.                             try
  109.                                // Make Thumb
  110.                                BgraThumb := BgraCurrent.Resample(ps.x, ps.y, rmFineResample);
  111.  
  112.                                // Draw BG
  113.                                bgraPage.FillRect((x), y, (x) + (cellWidth-1), y + (cellHeight-1), frm.cbThumbBackground.ButtonColor);
  114.                                // Draw Thumb
  115.                                bgraThumb.Draw(bgraPage.canvas, ((x) + ((cellWidth div 2) - (ps.x div 2))), y, false);
  116.  
  117.                                // Cell Text
  118.                                txt := frm.memInformation.Lines.text;
  119.                                txt := renameMacro(frm.lvFiles.items.Item[a].caption, txt, a);
  120.                                txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  121.                                txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  122.                                txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  123.                                txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  124.                                txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  125.                                txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  126.                                bgraPage.FontName := frm.cboFont.Text;
  127.                                bgraPage.FontHeight := frm.seFontSize.value;
  128.  
  129.                                // Get Size
  130.                                sze := bgraPage.TextSize(txt);
  131.  
  132.                                // Output Cell Text
  133.                                if frm.chkShowInformation.checked then
  134.                                begin
  135.                                    if (sze.Width>=cellWidth) or (sze.height>=cellHeight) then
  136.                                    begin
  137.                                        rct.top := y + thHeight;
  138.                                        rct.left := x;
  139.                                        rct.Bottom := (y + cellHeight);
  140.                                        rct.Right := x + cellWidth;
  141.                                        bgraPage.TextRect(rct,txt,taCenter,tlCenter,ColorToBgra(frm.cbTextColor.ButtonColor));
  142.                                    end else bgraPage.TextOut(x + ((cellWidth div 2) - (sze.width div 2)), (y + thHeight), txt, frm.cbTextColor.ButtonColor);
  143.                                end;
  144.  
  145.                                // Increment
  146.                                x := succ(x) + cellWidth;
  147.                                if x>=((pgWidth - frm.seSheet_Margin.value) - thWidth) then
  148.                                begin
  149.                                     // Increment Y
  150.                                     y := succ(y) + cellHeight;
  151.                                     // Reset X
  152.                                     x := intMargin;
  153.                                     if y>=((pgHeight - frm.seSheet_Margin.value) - thHeight) then
  154.                                     begin
  155.  
  156.                                         // Reset Y Co-Ord
  157.                                         y := frm.seSheet_Margin.value;
  158.  
  159.                                         // Footer
  160.                                         bgraPage.FontName := frm.cboFont.Text;
  161.                                         bgraPage.FontHeight := 12;
  162.                                         txt := frm.txtFooter.text;
  163.                                         txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  164.                                         txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  165.                                         txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  166.                                         txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  167.                                         txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  168.                                         txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  169.                                         sze := bgraPage.TextSize(txt);
  170.                                         if frm.chkShowFooter.checked then
  171.                                            bgraPage.TextOut((pgWidth div 2) - (sze.width div 2), (pgHeight - sze.height), txt, BgraBlack);
  172.  
  173.  
  174.                                         // Filename
  175.                                         txt := ChangeFileExt(frm.txtFilename.text, '');
  176.                                         txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  177.                                         txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  178.                                         txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  179.                                         txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  180.                                         txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  181.                                         txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  182.                                         txt := BackSlash(frm.deOutput.directory) + txt;
  183.                                         if frm.cboType.itemIndex = 0 then txt := txt + '.tif'
  184.                                         else if frm.cboType.itemIndex = 1 then txt := txt + '.png'
  185.                                         else if frm.cboType.itemIndex = 2 then txt := txt + '.jpg'
  186.                                         else if frm.cboType.itemIndex = 3 then txt := txt + '.bmp'
  187.                                         else if frm.cboType.itemIndex = 4 then txt := txt + '.webp'
  188.                                         else if frm.cboType.itemIndex = 5 then txt := txt + '.avif'
  189.                                         else txt := txt + '.png';
  190.  
  191.                                         // Save File or add a page if TIF?
  192.                                         if fileExists(txt) then RecycleItem(txt, true, false, true);
  193.                                         application.ProcessMessages;
  194.                                         sleep(15);
  195.                                         application.ProcessMessages;
  196.                                         SaveBGRAToFile(txt, BgraPage);
  197.  
  198.                                         // Start new Page
  199.                                         BgraPage.SetSize(0,0);
  200.                                         BgraPage.SetSize(pgWidth, pgHeight);
  201.  
  202.                                         // Set background options
  203.                                         bgraPage.FillRect(0, 0, pgWidth, pgHeight, frm.cbSheetBackground.ButtonColor);
  204.  
  205.                                         // Header
  206.                                         bgraPage.FontName := frm.cboFont.Text;
  207.                                         txt := frm.txtHeader.text;
  208.                                         txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  209.                                         txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  210.                                         txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  211.                                         txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  212.                                         txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  213.                                         txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  214.                                         sze := bgraPage.TextSize(txt);
  215.                                         if frm.chkShowHeader.checked then
  216.                                            bgraPage.TextOut((pgWidth div 2) - (sze.width div 2), 0, txt, frm.cbTextColor.ButtonColor);
  217.  
  218.                                         // Increment page count
  219.                                         pgCount := succ(pgCount);
  220.                                     end;
  221.                                end;
  222.                             finally
  223.                                    bgraThumb.free;
  224.                             end;
  225.                         end;
  226.                      finally
  227.                             bgraCurrent.free;
  228.                      end;
  229.                 end;
  230.                 // Footer
  231.                 bgraPage.FontName := frm.cboFont.Text;
  232.                 txt := frm.txtFooter.text;
  233.                 txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  234.                 txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  235.                 txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  236.                 txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  237.                 txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  238.                 txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  239.                 sze := bgraPage.TextSize(txt);
  240.                 if frm.chkShowFooter.checked then
  241.                    bgraPage.TextOut((pgWidth div 2) - (sze.width div 2), (pgHeight - sze.height), txt, BgraBlack);
  242.  
  243.                 // Save Last Page
  244.                 txt := ChangeFileExt(frm.txtFilename.text, '');
  245.                 txt := StringReplaceAll(txt, '{page}', IntToStr(pgCount+1));
  246.                 txt := StringReplaceAll(txt, '{pageleadzero}', LeadZero(pgCount+1, false));
  247.                 txt := StringReplaceAll(txt, '{pageleadhundred}', LeadZero(pgCount+1, true));
  248.                 txt := StringReplaceAll(txt, '{pagetotal}', IntToStr(pgTotal));
  249.                 txt := StringReplaceAll(txt, '{pagetotalleadzero}', LeadZero(pgTotal, false));
  250.                 txt := StringReplaceAll(txt, '{pagetotalleadhundred}', LeadZero(pgTotal, true));
  251.                 txt := BackSlash(frm.deOutput.directory) + txt;
  252.                 if frm.cboType.itemIndex = 0 then txt := txt + '.tif'
  253.                 else if frm.cboType.itemIndex = 1 then txt := txt + '.png'
  254.                 else if frm.cboType.itemIndex = 2 then txt := txt + '.jpg'
  255.                 else if frm.cboType.itemIndex = 3 then txt := txt + '.bmp'
  256.                 else if frm.cboType.itemIndex = 4 then txt := txt + '.webp'
  257.                 else if frm.cboType.itemIndex = 5 then txt := txt + '.avif'
  258.                 else txt := txt + '.png';
  259.                 SaveBGRAToFile(txt, BgraPage);
  260.              finally
  261.                     bgraPage.free;
  262.              end;
  263.  
  264.              try
  265.                 if ask('Open output in directory browser?')=mrYes then
  266.                    LoadAnyFile(BackSlash(frm.deOutput.directory));
  267.              except
  268.                    //
  269.              end;
  270.         end;
  271.      finally
  272.             frm.free;
  273.      end;
  274. end;
  275.  

It essentially makes a contact sheet, and as I mentioned this may be more math than graphics, the thumbs layout mostly correctly but I wanted to center them.  They can be of a fairly arbitrary size and the sheet can be too, so I need to work out on the fly where to start painting the thumbs.  Math is a HUGE weakness for me so any help would be gratefully recieved here, and perhaps if the routine can be made better I'm sure open to suggestions :)

CJ

 

TinyPortal © 2005-2018