In gezoomtes TImage pasten



  • Hi Omega-X 🙂

    Freut mich, dass Du noch mit dem ImageScroller arbeitest. 🙂

    Nenn 'mal genauer, was Du vorhast:
    - Eine Graphic vom Clipboard in das FImage an spezielle Position kopieren?

    - Was ist PastImage genau, was enthaelt das??

    (Villeicht ist das hinzubekommen.) 😃



  • Hi DerAltenburger,

    klar bau ich weiter :p . Im vorhandenen Projekt optimier ich die Functionen, dann kann ich sie in den ImageScroller integrieren. Direkt in der Klasse bring ich die Übersicht noch nicht zusammen.

    Das Paste-Image ist ein TImage. Das leg ich Top/Left auf FImage ab, füg das Bild der Zwischenablage ein, dann zoom ich es mit dem gleichen Faktor wie das FImage.

    void __fastcall TPixi::PasteClick(TObject *Sender)
    {
        if(Clipboard()->HasFormat(CF_BITMAP))
        {
            MarkBase->Left = Image->Canvas->ClipRect.Left;
            MarkBase->Top = Image->Canvas->ClipRect.Top;
            MarkBase->AutoSize = true;
            MarkBase->Stretch = false;
            MarkBase->Show();
            MarkBase->Picture->Assign(Clipboard());
            MarkBase->AutoSize = false;
            MarkBase->Stretch = true;
            MarkBase->Width = MarkBase->Width*VFac;
            MarkBase->Height = MarkBase->Height*VFac;
        }
    }
    

    Dann wird es an die gewünschte Position verschoben, das TRect dort festgelegt und das Bild an der Stelle ins FImage eingefügt. (Also genau das, was man in einem Malprogramm braucht, verschieb- und positionierbares Pasten. 🙂 ).

    Jetzt knobel ich an der Koordinatenumrechnung für das TRect, mit welchem ich festleg, wo im FImage das Bild aus MarkBase eingefügt werden soll. Noch kein brauchbarer Ansatz.



  • Original erstellt von <Omega-X>:
    Ist jetzt klar, was ich meine oder braucht es noch Infos?

    Sorry Omega, aber du drückst dich derart aus, dass dich einfach kein Mensch versteht. Versuch mal, dich so auszudrücken, wie es ein kleines Kind machen würde - ohne hochtrabende Worte. Vielleicht geht es dann besser. Und: Gehe auf den Helfenden ein! Zum Beispiel wären Infos, wo sich die beiden Images befinden nicht übel.



  • ...also die Wortwahl isses. Da muß ich drauf achten. Danke, @WebFritzi.

    Eine TScrollBox nimmt den gesamten freien Clientbereich der Form ein. Darauf liegt zentriert das TImage, in dem gemalt (und eingefügt) wird. Bei kleineren Bildern nimmt das Image nie den ganzen Raum der ScrollBox ein und wird darin zentriert.

    Beim Pasten wird ein TImage Top/Left auf dem Arbeits-Image plaziert. Dahin paste ich von der zwischenablage. Dann kann das Paste-Image via Drag&Drop verschoben werden. Verschieben teilweise oder ganz über das Arbeits-Image hinaus ist möglich.

    Befindet sich das Paste-Image am gewünschten Platz, wird an dessen Platz ein TRect positioniert. Vom Paste-Image aus wird das Bild via CopyRect in das TRect im Arbeits-Image eingefügt.

    Da sowohl Arbeits-Image als auch paste-Image mit dem gleichen Faktor gezoomt sind, befindet sich das TRect am logischen Platz der Erstellung. Benötigt wird es aber am physikalischen Platz in der Picture->Graphic. Ich muß die Koordinaten umrechnen. Ich finde aber keinen Algor, der in jeder Situation richtig arbeitet. Das einzufügende Bild gelangt also nicht an den Platz, an den es soll.



  • Bis zum letzten Absatz ist dein Beitrag und deine Beschreibung völlig OK. So wünscht man es sich. Super, dachte ich. Nur dann der letzte Absatz. Was ist der "logische Platz" und der "physikalische Platz"??? Versuche, auf solche Blödsinns-Ausdrücke zu verzichten. Der Helfer hat so keine andere Wahl, als die Ausdrücke zu deuten und zu interpretieren. Ich interpretiere das mal so: Das Paste-Image befindet sich über dem Image genau dort, wo es sein soll. Nun soll der Inhalt des Paste-Images in das Image genau an dieser Stelle kopiert werden. Ist das so richtig?? Wenn ja, dann verstehe ich nicht, warum dein "Algorithmus" von oben (erster Beitrag) nicht funktioniert. Er muss funktionieren!
    Mir ist da noch was aufgefallen:

    Die Positionsberechnung bezieht sich auf die Form.

    Das Image befindet sich in einer ScrollBox, richtig? D.h., die Eigenschaften Left und Top beziehen sich auf die ScrollBox und nicht auf die Form.

    [EDIT] Jau, das muss der Fehler sein! Du musst darauf achten, dass das PasteImage und das Image das gleiche Parent haben - in diesem Falle die ScrollBox. [/EDIT]

    [ Dieser Beitrag wurde am 09.03.2003 um 13:21 Uhr von WebFritzi editiert. ]



  • Hi Omega-X

    Folgende Ueberlegung:

    Dein FImage wird z.B. mit VFac=0.5 angezeigt.
      Das 'gepastete' Image skalierst Du gleich.
      ->In Scrollbox (Am Bildschirm erscheinen beide in halber Groesse!!!
    
      Das 'gepastet' Image positioniers Du z.B. 50 Pixel weiter rechts (DX)
      und 100 Pixel tiefer (DY).
      ->Auf FImage- Inhalt bezogen macht das das Doppelte (VFac!!!) ;) 
        ->DRect->Left muss 2x50 =100 sein
        ->DRect->Top  muss 2x100=200 sein.
    
    :::Positionsdifferenzen muessen DURCH VFac DIVIDIERT werden!!!(typecast nach double nehmen!!! :D 
    
    :::Die Groessenskalierung muesste mit 1:1 OK sein (das machen die gezoomten Images!)
    


  • Ja, hab inzwischen auch gemerxt, die ScrollBox liefert als fensterorientierter Parent den Koordinatenbezug. Wußte ich noch nicht, das stört hier aber zT. kollossal. Die Berechnungen beziehen sich auf den sichtbaren Bereich der ScrollBox. Mit den Zeilen

    MarkBase->Left = Image->Canvas->ClipRect.Left;
    MarkBase->Top = Image->Canvas->ClipRect.Top;

    wird MarkBase Top/Left in der ScrollBox positioniert, nicht Top/Left über dem Image (versteh aber nicht, warum, die Anweisung scheint klar zu sein). Usw. Ich bekomm nie einen immer richtig arbeitenden Algor. Probs hab ich auch, die Strecken außerhalb und innerhalb des Image zu berechnen. Beim Wechsel der Vergrößerung kann ich ua. die Position den MarkBase-Image nicht halten.

    @WebFritzi, die Begriffe "logisch" und "physikalisch" hab ich aus dem Buch "C++ Builder3 im Team, C&L". Muß ich akzeptieren, daß die Begriffe nicht allgemein gebräuchlich sind, sorry.

    @DerAltenburger, die Methode, mit festen Werten je Faktor zu arbeiten, muß ich probieren. Das ist immer genau, eine Division nicht unbedingt. ... Hey, erst beim 2. Lesen seh ich, daß mit (DX) und (DY) alles fein normierbar aufgebaut werden kann. Ein Bedingungssatz statt der Division, das wird exakt. 🕶

    Du schlägst sogar double vor, nicht float? float sollte weit mehr können, als ich in einem (größeren) Bild benötige. Aber einfach mal checken... Aber s.O., ich seh so aus, als ob mir das viiieel besser gefällt. :p

    Bei 1:1 hab ich keine Probs.

    Ole, war dann auf eine andere Basislösung gekommen, bei der die Probs vermieden werden. Ich leg die beiden TImage's Image und MarkBase auf einem Panel ab. Das Panel paßt sich bei jeder ändernden Operation dem Image an. Damit hab ich einen eindeutigen Bezug für alle Operationen. Jetzt kann ich so scalieren, wie es auch beim Malen klappt. - Muß aber noch den Code gründlich durchgehen und alles anpassen. Ich denk, damit sollte ich aus dem Schneider sein, ich sag dann bescheid.

    <edit>Es wird wirklich interessant sein, wenn alles stimmt, aus dem Aufbaukomplex eine Kompo zu machen. Aber Operationen würde ich nicht mit reinnehmen. Nur die Methoden wie zB. Canvas->LineTo..., aber auch zB. die Synchronschaltung von FImage und FPanel, die wahlfreie Zentrierung/Positionierung in der Scrollbox, ZoomHandling usw.</edit>



  • MarkBase->Parent = ScrollBox;
    


  • @Webfritzi

    Tust Du ueberhaupt wissen tun ueber was fuerne Komponente hier diskutiert wird? 😃



  • Ja. Über deine tolle Komponente, du Angeber. 😉



  • Dann haeteste Dir Dein' vorletzten Beitrag sparen koennen! 😃

    PS: Den letzten auch! :p

    [ Dieser Beitrag wurde am 09.03.2003 um 22:44 Uhr von DerAltenburger editiert. ]



  • Wir hätten uns beide die letzten Beiträge sparen können, wenn du hier nicht so geheimnisvoll darüber reden würdest. Nun mal raus damit.



  • @WebFritzi

    Fuer Dich blinden Uhu nochmal langsaaaaaaaaam!:

    Lies den Beitrag 'Bild- Viewer Problem' von <GOMEZ> vom 2.3.2003 nochmal genau durch! Dann kannste vieleicht mitreden, was hier gebastelt wird. 😃

    DAS WIRD DIE FORTSETZUNG!!!

    War das langsaaaaaam genug? 😃

    PS: Haettest Du damals mitgelesen und nicht nur 'Reingequatscht, gaeb's nun kein Problem! 🕶

    [ Dieser Beitrag wurde am 09.03.2003 um 23:10 Uhr von DerAltenburger editiert. ]



  • Original erstellt von DerAltenburger:
    Haettest Du damals mitgelesen und nicht nur 'Reingequatscht, gaeb's nun kein Problem! 🕶

    *vogelzeig* Du tust ja gerade so, als wäre deine blöde Kompo diejenige, zu der man sich jeden Thread anschauen muss. Ich hab anderes zu tun und bastel lieber an guten Kompos.



  • Verwarnung an DerAltenburger und WebFritzi, bitte sachlich und beim Thema bleiben!



  • :p ... Wer haut sich denn schon um gute Kompos?. Das lohnt sich höchstens um die goooilste Kopmo. Und das kann daauuuern. 😃

    Schluß mit Peter Lustig 😉 , Image liegt also zentriert in der ScrollBox auf einem identisch justierten Panel. Parent von MarkBase ist auch das Panel. Das Bild von MarkBase wird jetzt richtig ins Image eingefügt.

    void __fastcall TPixi::MarkBaseImageMouseDown(TObject *Sender, TMouseButton Button,
                TShiftState Shift, int X, int Y)
    {
        FDragging = false;
        // double wäre gar nicht nötig, hab keinen Unterschied entdeckt
        MarkBase->Left = (int)((double)MarkBase->Left/VFac);  
        MarkBase->Top = (int)((double)MarkBase->Top/VFac);
        DRect.Left = MarkBase->Left;
        DRect.Top = MarkBase->Top;
        DRect.Right = MarkBase->Left+MarkBase->Width;
        DRect.Bottom = MarkBase->Top+MarkBase->Height;
        Image->Canvas->CopyRect(DRect, MarkBase->Canvas, MarkBase->ClientRect);
        MarkBase->Hide();
        MarkBase->Picture = NULL;
        MarkBase->Width = 1;
        MarkBase->Height = 1;
        DRect = Rect(0,0,0,0);
    }
    

    Bei +Zoom klappt es, bei -Zoom wird das eingefügte Bild proportional kleiner. Klar, Bildinfos gehen verloren. Pasten wird also erst ab 100% Sinn machen, darunter werd ich die Function sperren.

    Vorher wurde MarkBase verschoben:

    /* Im MarkBaseMouseDown:
    (int - global) markleft = X, marktop = Y;
    void __fastcall TPixi::MarkBaseMouseMove(TObject *Sender,
                TShiftState Shift, int X, int Y)
    {
        Screen->Cursor = crHand;
        if(Shift.Contains(ssLeft))
        {
            MarkBase->Left = MarkBase->Left + X - markleft;
            MarkBase->Top = MarkBase->Top + Y - marktop;
            /* Zu brutal, bin mit einem Schlag an der Scrollgrenze.
               Suche was besseres */
            // ScrollBox->ScrollInView(MarkBase);
        }
    }
    

    Bei Vergrößerungen wird weiterhin nach Canvas-Pixeln verschoben. Die Bild-Pixel sind größer, ich kann also auch auf Zwischenpositionen verschieben. Beim Einfügen wird dann auf das nächstgelegene Pixel in Top/Left-Richtung korrigiert. Ob sich das noch verbessern läßt? Ich wollte im jeweils aktuellen Bildpixelraster verschieben können. Mir fällt im Moment kein Algor ein. Hat jemand 'ne Idee?



  • *Bin geleidigt* Der BCB3 kennt kein DoubleBuffered. Aber ich verschieb hier ein gezoomtes TImage in einem gezoomten TImage. Da hat der das zu kennen! :o 😃 Oder auf hochdeutsch: Je gezoomt, desto langsamere Refreshrate. Das Flickert wie'd Sau.

    Genügend Threads, einiges probiert, es will nicht besser werden. Hab trotzdem eine Lösung:

    if(Shift.Contains(ssLeft))
        {
            MarkBase->Refresh();
            MarkBase->Left = MarkBase->Left + X - markleft;
            MarkBase->Top = MarkBase->Top + Y - marktop;
            MarkBase->Refresh();
        }
    

    MarkBase läuft jetzt schön glatt. Der Preis: Image refresht während dem Verschieben des MarkBase nicht, das Bild wird total zugeschmiert, bis ich das Verschieben kurz unterbreche.

    Gibt es da noch einen Trick? Bzw, wäre ggf. für das DoubleBuffering eine Bibliothek einzubinden, die man irgendwo bekommen kann - BCB3-kompatibel natürlich?



  • Hi

    : Das mit dem double ist nur 'ne Angewohnheit 😉 , float geht auch (mit double sind Rundungsfehler geringer)

    :Was bedeutet 'bei -Zoom wird Bild kleiner'? Es muesste kleiner angezeigtwerden.
    Die Proportion zum Ausgangsbild muesste bei jedem Zoom stimmen? 😉
    :Beim Verschieben soll sich das Paste- Bild am Pixelraster des Ausgangsbildes orientieren? 😕

    ->Berechnete Position (Anzeigepixel) 'hochrechnen' auf Originalmassstab, runden auf Ganzzahl (BildPixel), wieder 'runterrechnen'.(Dann muesste das beim Schieben mit z.B. 200% Zoom in 2xPixel- Schritten einrasten)

    Das mit dem Flackern ist echt Mist! Ist nur bei 100% Zoom ertraeglich und bei nicht zu grossen Bildern. 😕

    ->eventuell besser:

    Ausgangsbild und 'gepastetes' Bild in eigenes Bitmap speichern(Offscreen)
      Bei Bewegung beide in weiteres Bitmap 'mischen'
      Gemischtes Bitmap in Anzeige zeichnen
      : etwas aufwaendig!
      (Ausgangsbild koennte auch aus TImage benutzt werden (unsichtbar!).
      Anzeige in anderes TImage, wie beim malen)
      :Mischen nicht in der Anzeige selbst machen(Flimmert wie 's Tier)
    


  • Hai, schon wieder aktiv? Ich konnte gar nicht Stop machen. Mußte eben noch "Hilfslinie auf einem TImage" Hilfslinie auf einem TImage checken, war irgendwie Pflicht. 😉 Der Algor von @AndreasW gefällt mir echt. Mein Dank hier, denn im Thread gibt's nichts hinzuzufügen. - Das wird dann ein Fall für's 2. Image. Das bring ich erst rein, wenn alles mal so läuft. 🙂

    Beim Zoomen wird das Bild nicht kleiner, als es soll. Aber das gepastete Bild ist deutlich kleiner als die Größe von MarkBase. Bei 25% Zoom schrumpft es etwa auf 1/4. Das sind also nicht die Bildinfos, wie ich erst dachte. Das Paste-Bild wird deutlich beschnitten.

    Kann mir das jetzt nicht erklären. Der Effekt war ursprünglich nicht. Ich korrigier allerdings jetzt die Position von MarkBase, dann übertrag ich das DRect ohne Umrechnung. Nach meiner Logik solte das der simpelste und zuverlässigste Weg sein. Möglicherweise ist das der Fehler. Komisch ist nur, das müßte sich genauso auf Vergrößerungen auswirken, tut es aber nicht. Hier bin ich also noch am Rätseln.

    Ungefähr versteh ich, wie du das mit dem Hochrechnen beim Rasterverschieben meinst. Bei 200% verschieb ich um 2^n, bei 500% um 5^n. Aber wie drück ich das im Code aus? Vielleicht so?:

    if (fmod(MarkBase->Left,VFac) != 0)
            MarkBase->Left += (VFac-fmod(MarkBase->Left,VFac)); 
        if (fmod(MarkBase->Top,VFac) != 0)
            MarkBase->Top += (VFac-fmod(MarkBase->Top,VFac));
    

    *Treffer... versenkt* 😃 - Komisch, erst durch deine Anregung kam ich drauf, obwohl ich die gar nicht so doll verstanden hatte. Der Effekt ist aber nicht neu.

    Jetzt noch das Mischen. Uff... ist weder Wodka noch Martini drin. Aber einfach mal drangeh'n... 🙄

    Für das AutoScrollen, wenn MarkBase über Width/Height der scrollBox hinausverschoben wird, such ich immer noch eine gute Idee. Mit X, ScrollBox->Width, Position gelang nichts - sollte aber eigentlich (IMHO). Steh wohl auf der Leitung.



  • Du willst doch das 'Paste- Image' komplett einfuegen, oder nicht?

    Das muesste ohne Rect's gehen. Mit Draw(...) nur linke obere Ecke angeben;was nicht in Ausgangsbild passt, wird abgeschnitten. 😉

    Oder soll Einfuegen mit anderem Faktor erfolgen (dann geht's so nicht)

    Mit:
    DRect.Right = MarkBase->Left+MarkBase->Width;
    DRect.Bottom = MarkBase->Top+MarkBase->Height;
    wird doch 'Zielrechteck' berechnet? 😕

    ??? sollten Hoehe und Breite nicht in Original- Pixelgroesse vorliegen???
    ???MarkBase->Width ist aber doch die Abmessung des 'gezoomten' TImage ???

    Ich denk, das muss skaliert sein (VFac) 😕

    [ Dieser Beitrag wurde am 10.03.2003 um 13:24 Uhr von DerAltenburger editiert. ]


Anmelden zum Antworten