Jump to content

Anders Melander

Members
  • Content Count

    2265
  • Joined

  • Last visited

  • Days Won

    117

Posts posted by Anders Melander


  1. 1 hour ago, Dalija Prasnikar said:

    This was due to Turbo Pascal legacy. 

    ISO7185 (anno 1982) would like a word with you about that:

    Quote

    Any type designated packed and denoted by an array-type having as its index-type a denotation of
    a subrange-type specifying a smallest value of 1 and a largest value of greater than 1, and having as
    its component-type a denotation of the char-type, shall be designated a string-type.

     

    There weren't, to my knowledge, any formal standards before this (the ANSI standard came 1983) but strings has been 1-based since the beginning.


  2. Okay, so you are trying to interface to an external COM library. From the name of the interface I'm guessing this is the interface:

    https://ascom-standards.org/Help/Developer/html/T_ASCOM_DeviceInterface_ITelescopeV3.htm

     

    As you can read in the documentation...

    https://ascom-standards.org/Help/Developer/html/e7734c14-0562-4010-b0c9-ddb5055cd318.htm

    ...there should be a type library that you can use.

     

    The easiest way to use this type library is to have Delphi create a wrapper for you:

    1. From the Delphi IDE menu, select Component->Import Component...
    2. Select Import a Type Library
    3. Find the type library in the list or select Add and find it on your disk.
    4. Edit the Unit Dir Name to place the generated wrapper source code in your project source folder.
      I do not recommend that you select "Generate Component Wrappers".
    5. Select Add unit to <name of your project> project.

    Delphi will now have created a source file containing all the interfaces, dispinterfaces, enums, coclasses, etc. of the type library.

    In order to communicate with the library you will first have to create an instance of a COM object from it. There should be a function in the generated source that will do that for you but since I don't know the library I can't tell what the name of that function is.

    If you have some example code, in C, C++ or VB, it should be easy to see from that what you need to do. Post it if you have it and we can take it from there.


  3. You can't do the fade-in from the constructor because the form isn't visible at that point.

    So:

    1. Create the form.
    2. Set MasterAlpha=0
    3. Show the form
    4. Fade in

    I suggest you simply override ShowScreen:

    procedure TGameBaseScreen.ShowScreen;
    begin
      ScreenImg.Bitmap.MasterAlpha := 0;
      inherited; // Form is made visible here
      FadeIn;
    end;

    And there was an endless loop in the Fade in method. This one works:

    procedure TGameBaseScreen.FadeIn;
    var
      EndTickCount: Cardinal;
      TickCount: Cardinal;
      Progress: Integer;
      Alpha, LastAlpha: integer;
    const
      MAX_TIME = 1000; // mS
    begin
      ScreenImg.Bitmap.DrawMode := dmBlend; // So MasterAlpha is used to draw the bitmap
    
      TickCount := GetTickCount;
      EndTickCount := TickCount + MAX_TIME;
      LastAlpha := -1;
    
      while (TickCount <= EndTickCount) do
      begin
        Progress := Min(TickCount - (EndTickCount - MAX_TIME), MAX_TIME);
    
        Alpha := MulDiv(255, Progress, MAX_TIME);
    
        if (Alpha <> LastAlpha) then
        begin
          ScreenImg.Bitmap.MasterAlpha := Alpha;
          ScreenImg.Update;
    
          LastAlpha := Alpha;
        end else
          Sleep(1);
    
        TickCount := GetTickCount;
      end;
      ScreenImg.Bitmap.MasterAlpha := 255;
    end;

     


  4. By bad; Change this:

    Progress := Max(TickCount - EndTickCount - MAX_TIME, MAX_TIME);

    to this:

    Progress := Max(TickCount - (EndTickCount - MAX_TIME), MAX_TIME);

     

    EndTickCount = StartTickCount + MAX_TIME <=>
    StartTickCount = EndTickCount - MAX_TIME

    so

    Elapsed time = TickCount - StartTickCount <=>

    Elapsed time = TickCount - (EndTickCount - MAX_TIME)

     


  5. Something like this:

    procedure TGameBaseScreen.FadeIn;
    var
      EndTickCount: Cardinal;
      TickCount: Cardinal;
      Progress: Integer;
      Alpha, LastAlpha: integer;
    const
      MAX_TIME = 1000; // mS
    begin
      ScreenImg.Bitmap.DrawMode := dmBlend; // So MasterAlpha is used to draw the bitmap
    
      TickCount := GetTickCount;
      EndTickCount := TickCount + MAX_TIME;
      LastAlpha := -1;
    
      while (TickCount <= EndTickCount) do
      begin
        Progress := Max(TickCount - EndTickCount - MAX_TIME, MAX_TIME);
    
        Alpha := MulDiv(255, Progress, MAX_TIME);
    
        if (Alpha = LastAlpha) then
        begin
          Sleep(1);
          continue;
        end;
    
        ScreenImg.Bitmap.MasterAlpha := Alpha;
        ScreenImg.Update;
    
        LastAlpha := Alpha;
        TickCount := GetTickCount;
      end;
      ScreenImg.Bitmap.MasterAlpha := 255;
    
      Application.ProcessMessages;
    end;

     


  6. 2 hours ago, angusj said:

    It's a problem with the Graphics32 library too if TAffineTransformation is used to do the scaling.

    True. Luckily nobody does that 🙂

     

    Here's the bitmap resized with TAffineTransformation.Scale(0.1, 0.1) and TKernelResampler with TCubicKernel:

    xxx.png.58a1536963176de70a0abb097481518a.png

    So pretty much as bad as yours:

    bicubic.png.ce700be559337a4c4d1d69287bb1412d.png

     

    But anyway, I think we can conclude that the problem isn't with the cubic filter itself but more with how it's applied.


  7. 23 minutes ago, angusj said:

    If you avoid using TAffineTransformation, and just use a resampler together with a renderer, then you do avoid this issue with pixelation.

    (In my Image32 graphics library, I use affine transformations without a renderer.)

    So: A problem in your implementation - or rather a consequence of the way you have chosen to implement resizing images. Or did I misunderstand what you just wrote?


  8. 11 hours ago, angusj said:

    Yet here's a more extreme example of downsampling (scaled to 0.1 of original size) where the quality differences are very noticeable:

    It looks to me as if there's a problem in your implementation... Here's what I get with a selection of Graphics32 kernels:

    Box

    image.png.ef31af6b1381047cd458dba37052a35a.png

     

    Cubic

    image.png.aa06c1e3d34aad656582ce4a25655df8.png

     

    Linear

    image.png.954ed10f4742096400f2b50789cb4dbe.png

     

    Cosine

    image.png.74d2c59a8703d45bac55a5008b24c314.png

     

    Spline

    image.png.7df63ab3e31f2223ea4d2c527d6e3f20.png

     

    Hermite

    image.png.fc698c10ccd91025c945a7ca1d324cda.png

     

    Yes, there are differences but IMO they all look good. Even Spline which shouldn't really be used for down-sampling.

     

    Ignore the black line at the top of each image; It's caused by a bug in Firefox's clipboard handling of 32-bit RGBA bitmaps:


  9. Yes, you are going to use IOTA but you really need to read up on this topic until you understand it.

     

    The basic steps you must take is something like this (pseudo code; don't try to compile it):

    // Open the file in the IDE
    (BorlandIDEServices as IOTAActionServices).OpenFile('my_unit.pas');
    
    // Get the file "module"
    var Module: IOTAModule := (BorlandIDEServices as IOTAModuleServices).FindModule('my_unit.pas');
    
    // Iterate the module files
    for var i := 0 to Module.GetModuleFileCount-1 do
    begin
    
    // Get a module file editor
      var Editor: IOTASourceEditor;
      if not Supports(Module.GetModuleFileEditor(i), IOTASourceEditor, Editor) then
        continue;
    
      // Make the editor visible
      Editor.Show
    
      // Get an editor view
      if (Editor.GetEditViewCount = 0) then
        continue;
      var EditView: IOTAEditView := Editor.GetEditView(0);
      
      // Set the caret position
      var Position: TOTAEditPos;
      Position.Col := 1;
      Position.Line := ...
      EditView.SetCursorPos(Position);
      
      // Scroll to make caret visible and 15 lines down from the top
      Position.Line := Max(1, Position.Line-15);
      SetView.SetTopPos(Position);
    end;
    • Like 3

  10. 1 hour ago, FreeDelphiPascal said:

    I need the final image as pf8. But if I set its PixelFormat to pf8, some wavy patterns appear in it

    Please google color quantization and dithering.

     

    1 hour ago, FreeDelphiPascal said:

    like when you convert a high color image to 256 color GIF

    Because that's exactly what you are doing.


  11. Yes, that's normal.

    Right click in the Events pane, select Properties and then unselect Process, Thread and Module messages. Unless you really need the information it's just noise.

    image.thumb.png.6b06b989701f7c3231a78403c5407c36.png

    • Thanks 1

  12. I think the MS documentation, while a bit terse, is clear enough; It specifies how the different properties and their limits relate to each other.

    The Delphi documentation though is severely lacking. If they had tried to document it properly they would probably have discovered that they got it wrong.


  13.  

    29 minutes ago, cecarnicom said:

    but still a mystery to me why such low limits would exist for an image component

    Maybe you should think a bit more about that. Ideally until it is no longer a mystery.

     

    What possible reason could there be for that limit? The 16x16 default is a big clue...

    • Like 2
×