Bitmap hochauflösend verkleinern
-
Original erstellt von Jansen:
**Genau. Aber warum der Umweg über SrcCanvas, du kannst doch direkt die Form abkopieren!?SrcBmp->Canvas->CopyRect(ClientRect, Canvas, ClientRect);
**
Nö. Das ist nur das ClientRect und nicht die ganze Form.
[ Dieser Beitrag wurde am 12.01.2003 um 00:39 Uhr von WebFritzi editiert. ]
-
Na gut, das können wir gerade so gelten lassen.
-
@etechniker, wenn ich mit PenWidth = 8 zeichne, bekomm ich eine grobpixelige Grafik. Pixel ist nichts weiter als ein definiertes Flächenmaß bezogen auf die ScreenAuflösung (sofern ich es nicht falsch verstanden hab). Die Dinger können auch viel kleiner sein als 1. Ich hab schon mit
PenWidth = 1 / 30;
und ähnlichem gearbeitet. Tatsächlich kann ich in einem Bitmap hochauflösend retuschieren. Sehr viele kleine Pixel in ein einziges normalgroßes Pixel. Hochauflösender Grafik begenet man auch in der Praxis. Teure Bildformate und auch einige moderne Spiele. In der Grafik-Engine (3D), zB. von acknex kann ich die Texturen skalieren. Beim Näherkommen sieht man keine verpixelten Grafiken, wie in den klassischen Spielen. Unser Burgenspezialist hat den Bogen schon so raus, daß man sich in den Räumen vorkommt wie in einer wirklichen Umgebung. Pixel verkleinern ist also technisch und vom Bedarf her völlig zeitgemäß.
Ole, und jetzt will ich als oller Storyteller und noch nicht sehr weit fortgeschrittener (eigentlich fast noch Starter) Coder Itemgrafiken vom Feinsten kreieren. Denn wir bauen ja nicht die gähnenede Langeweile nach sondern wenn schon, denn schon incl. komplexer Abenteuerstory - also nicht nur immer dieser selbst die Langeweile tötende Kampf bis zum Abwinken. - Aber das nur am Rande wegen dem Grund für mein skurilles Anliegen. :p
@WebFritzi, super Dank! Den Konstruct hatte ich erst NULL verstanden, bis ich das gespeicherte Ergebnis sah. Ein gewaltiger Fortschritt. Das Original-Schwert hatte zB. eine 20 Pixel breite Klinge, die 5-fache Verkleinerung immerhin 10. (Über Kopiertechniken schaff ich nur etwa 3 Pixel, halt das übliche lineare Vorgehen). Hier ist schon erstaunliches möglich, ohne überhaupt "geschraubt" zu haben. Den Code muß ich jetzt nur noch anpassen und die Aufgabe den Komponenten übertragen.
Ääähhh..., bin ich unverschämt? Ich bin unverschämt und ausdauernd, wenn es um Neugier Erreichnisse geht. Aber Neugier ist nun mal die Seele, wenngleich auch noch kein Plan besteht. Wenn irgendwie rankommbar, wollte ich es noch eine Stufe feiner haben. Ich seh in detailreichen Miniaturen noch die idealisierten Pixel, die Übergänge müßte man mühsam reinretuschieren. Aber mir fällt nichts ein, wie ich an die Pixel selbst drankommen könnte. Geht immer nur beim manuellen Zeichnen. Ich expirimentier natürlich weiter. Aber wenn jemand eine Idee hat, das wär *atomar*.
-
Also mit SrcCanvas bring ich einen Fehler rein. Auch wenn ich das Rect von "Start" angebe, wird der Bildausschnitt ab Top/Left der Form incl WindowLeiste genommen. Ohne diesen Zwischenpart klappt es UFB. Start übergibt nach dem Laden an SrcBmp, stretchdrawt nach DestBmp, von dort aus assigne ich es nach "Ziel".
Hab ziemlich expirimentiert aber keine Möglichkeit gefunden, Pen->Width zu integrieren. Geht wohl doch nur mit ScanLine? Ich bring da aber nichts zusammen, das Bild bleibt schwarz. Hier nochmal der Code, wie er bis jetzt aussieht:
void __fastcall TResa::ButtonEnter(TObject *Sender) { Ziel->Width = StrToInt(EditX->Text); Ziel->Height = StrToInt(EditY->Text); Graphics::TBitmap* SrcBmp = new Graphics::TBitmap; SrcBmp->Width = Start->Width; SrcBmp->Height = Start->Height; SrcBmp->Canvas->Pen->Width = 30; SrcBmp->Assign(Start->Picture->Graphic); Graphics::TBitmap* DestBmp = new Graphics::TBitmap; DestBmp->Width = Ziel->Width; DestBmp->Height = Ziel->Height; RECT DestRect = Rect(0, 0, Ziel->Width, Ziel->Height); DestBmp->Canvas->Pen->Width = 30; DestBmp->Canvas->StretchDraw(DestRect, SrcBmp); Ziel->Picture->Assign(DestBmp); delete SrcBmp; SrcBmp = NULL; Ziel->Picture->SaveToFile("Check.BMP"); delete DestBmp; DestBmp = NULL; }
Also wenn jemand eine Idee hat, auf welche Art man die Auflösung noch feiner bekommen kann, :p
NachPS: Eigentlich bin ich angemeldet. Login oder Profil einsehen klappt allerdings nicht. Ich werd immer im Kreis geführt. - Aber ich fall ja durch fast jede Gesichtskontrolle durch.
-
Original erstellt von <Omega-X>:
**@etechniker, wenn ich mit PenWidth = 8 zeichne, bekomm ich eine grobpixelige Grafik. Pixel ist nichts weiter als ein definiertes Flächenmaß bezogen auf die ScreenAuflösung (sofern ich es nicht falsch verstanden hab). Die Dinger können auch viel kleiner sein als 1. Ich hab schon mitPenWidth = 1 / 30;
**
Pixel verkleinern ist Blödsin, du meintest ja dadurch Speicherplatz zu sparen.
Wenn du mit einer PenWidth von 1/30 arbeitest bedeutet das das du das auf einem
Monitor erst darstellen kannst wenn du mit 30-facher vergrößerung arbeitest.
Was aber immer gleich bleibt ist der Speicherplatz den du für einen Pixel
benötigtst. Und bei einer Penwidth von 1/30 und einer ungescaleten Grafik benötigtest du für jeden Bildschirmpixel 30*30 gespeicherte Pixel, also 900mal
so viele gespeicherte Pixel pro Bildschirmpixel ohne einen Qualitätsunterschied zu sehen.Was hat das mit teuren ? Bildformaten zu tun, du kannst jedes beliebige Bildformat nehmen und einfach ein größeres Bild erstellen (z.B. 3000x2000) und es für die Darstellung auf dem Bildschirm entsprechend scalieren.
Naja, bevor ich zu den ganzen Kram antworte nochma zu deinem Hauptanliegen eine
Grafikdatei zu verkleinern indem du die Pixel verkleinerst... Das hat keinen Sinn weil die Datei auf der Platte für jeden Pixel, ob nun auf dem Bildschirm klein oder groß Dargestellt, dieselbe Information speichern muss.[ Dieser Beitrag wurde am 12.01.2003 um 10:53 Uhr von etechniker editiert. ]
-
Ich werd mich bremsen können, den Testcode in der Praxis anzuwenden. Die fps gehen in den Keller, uzw. gnadenlos. Dein Beispiel mit den 900 Pixeln sagt da alles. Das war nur mal ein Wert, um sofort zu sehen, ob ein Effekt eintritt. Genauso hab ich Pen->Width = 30 eingesetzt. Erst, wenn ich überhaupt die Wirkung seh, kann ich an die Feinarbeit gehen.
Mir geht es also nicht um den Speicherplatz. Was in der Map längst unakzeptabel wäre, läuft aber mühelos noch in einem stehenden Itemschirm. Daß man in dem Bereich wirklich was für's Auge bieten kann, hab ich ua. schon in Manga-Spielen gesehen.
Mit etwa 1/4 würde ich durchaus mal experimentieren. Bei den etwa 1/2, die jetzt möglich sind, seh ich ja noch die Pixel aus der Distanz. Ist natürlich auch schon edel. Aber allzu detailreich dürfen die Grafiker da noch nicht aufbauen. Die verwenden ja hemmungslos die Bildschirmhöhe, um flüssig arbeiten zu können. Wischtechniken usw, das braucht Platz. Irgendwie muß man das dann auf die benötigten Größen trimmen.
-
Was du, soweit ich das sehe, vorhast (die Grafiken zur Laufzeit skalieren) ist aus Performancegründen nicht sinnvoll. Nicht umsonst halten professionelle Spiele die Texturen in verschiedenen Auflösungen vor und laden bei Bedarf eine der Entfernung (und somit der Grösse) des Bildobjektes entsprechende Version aus dem Speicher oder von Platte.
Du solltest also deine Grafiker ihre tollen Bilder malen lassen und diese dann in verschiedenen Auflösungen bzw. Grössen abspeichern. Die Skalier-Algorithmen der Grafikprogramme liefern ohnehin eine viel bessere Qualität als du sie (mit vertretbarem Aufwand) jemals selbst programmieren könntest.
-
Skalieren zur Laufzeit war noch gar nicht im Gespräch. Aber Nachladen wär echt eine Überlegung wert. Dein Tip kann Gold wert sein. Auf die Entfernung reichen grobpixelige Texturen, das spart jede menge Speicher. Ein Übriges tut dann Nebel.
Hier ginge es aber nur um die Itemgrafiken. Bei denen ist die Distanz immer gleich. Für's Gelände reichen dann schlichte Models, hauptsache, sie sind erkennbar. In Truhe und Handel sind es ja die Sprites wie im Itemschirm.
Ja, für Freeware lohnen sich die leistungstarken Anwendungen nicht. Wer es nicht sowieso hat... Deswegen ist mittelmäßig skaliert auch besser als gar nichts. Was man teilweise so bewundern kann, das wird ein Traum bleiben. Allerdings... die Bauzeit ist eher langfristig. Da kann noch einiges geschehen. Die Crew wird ja noch eine Weile im Aufbau sein...
-
Wenn du nicht zur Laufzeit skalieren willst dann brauchst du doch auch überhaupt kein StretchDraw oder vergleichbare Routinen!? Lade einfach die passende, vorgefertigte Grafik.
-
Ach, jetzt versteh ich deine Gedanken. Nein, das wird kein Feature fürs Spiel. Ich will nur ein Tool bauen, mit dem ich die meist zu groß geratenen Itemgrafiken auf die benötigte Größe bringen kann. Daß Details verloren gehen, ist klar. Aber es soll im Rahmen bleiben, so gut es geht.
Es fällt immer wieder auf, daß die Grafiker Probs haben, in den benotigten Größen was brauchbares hinzubekommen. Wenn ich nur an die tollen Ringe denk. Fast halb so hoch wie die Antwortform. Kleiner ging es wohl nicht bei der verwendeten Technik. Das Teilchen soll dann in ein 50 px hohes Feld reinpassen. Es geht, aber die investierte Kunst geht dabei ziemlich verloren. Das jetzt erreichte hilft kollossal. Nur noch ein klein wenig feiner, und es wär schon brillant. Wenn es gelingen will, will ich den Punkt natürlich anstreben.
-
Warum mußt du dafür selbst ein Tool bauen? Geht das nicht mit GIMP, Paint oder so?
-
Ganz meine Meinung. Wie ich schon sagte, an die Qualität der "Verkleinerungsfunktionen" von Grafikprogrammen wie Photoshop, Paintshop Pro usw. kommst du mit einem selbstgebauten Programm buchstäblich "nie im Leben" ran.
-
Huch, mit den Programmen geht das bereits? Eins davon hat doch jeder Grafiker. Natürlich nicht Paint, das wüßte sogar ich - denk ich zumindest. Ein Poserspezialist ist mal an 20 px hohen Button gescheitert. Wenn das Thema nicht schon öfter angestanden hätte, würd ich jetzt sagen, ich war vorschnell. Aber scheinbar ist es wirklich nicht so leicht, eine gute und interessierte Mannschaft zusammen zu bekommen. Die beklagen sich alle lieber, daß die Hersteller immer lascheres bringen - zocken aber konsequent weiter.
Ole, mein Builder soll nützlicheres kreieren als das sechseckige Rad nach jahrteusenden neu zu erfinden. :p Dank euch sehr für eure Hilfe. Auf jeden Fall hat es Erfahrung gebracht.
Mal seh'n, welche unnötige Frage mir als nächstes einfällt.
Gruß
Omega-X
-
Was heißt "bereits", Photoshop ist schon ziemlich geil, ich kenne nix besseres.
-
Huch, mit den Programmen geht das bereits? Eins davon hat doch jeder Grafiker. Natürlich nicht Paint, das wüßte sogar ich - denk ich zumindest.
Eine Datei in Paint öffnen -> [Menü]Bild->Strecken/Zerren...
-
Also hab ich mal Pause gemacht mit Knobeln und subjektiven Beobachtungen und ein Testbild genau auf 50% verkleinert. Von Paint wußte ich es bereits, von meinem Tool sah ich es jetzt. Aus 26 Px wurden genau 13, also keinerlei Gewinn. Für diesen Zweck haben wir etliche gute Möglichkeiten incl. der diversen Filter, die die Resampel-Komponente zT. auch integriert hat.
Wenn mein Screen 32 cm breit ist, sollte ich rein theoretisch unter 12800 schwarzen px gerade noch ein einzelnes weißes erkennen können. 800 ist also noch grob, aber angemessen für gute Performance. Da dürfen dann aber auch ein paar Leckerbissen für's Auge dabei sein, die einer Auflösungen 1 oder 2 Stufen höher entsprechen.
Wenn zB. PSP usw. genau das kann, schäm ich mich für unsere Grafiker, denn sie wissen es nicht mal. Wenn nicht, muß ich weitersuchen.
Wird allerdings nicht leicht, denn die Beispiele zum Reinfinden sind hyperrar und... von Borland. Kann mich des Eindrucks nict erwehren, daß die den Ball absichtlich flach halten, das aber in aufgedunsener Sprache kaschieren. Lassen die mich doch das enum DrawTool voll durchziehen, nur um am Ende zu sagen, daß das aber nur bei 4 Zeichentools stabil läuft. Und tatsächlich durfte ich meinen Code dann völlig anders aufbauen, das Zeug war instabil und ungenießbar. So nach dem Kalauer- und Spielereiprinzip kommt es mir immer wieder vor.
- Nach der Totalernüchterumg um "/page" im RichEdit hatte ich mich dann jahrelang um ganz andere Sachen gekümmert. Selbst der referierende RichEdit-Spezialist in den Borland-Foren konnte nur Fehlermeldungen ernten. Also sogar abgeriegelt, die Geschichte nach dem Prinzip des einzelnen Feldes, das das gesamte Schachbrett kontrolliert...
-
Hab mal die Routine zusammengepfrimelt. Wenn ich den Aktiosbutton klick, bekomm ich die Meldung aus dem Code. Das Bild im Ziel ist zur linken senkrechten Hälfte ein Graustufenwechsel in breiter Querbalkenform. Die rechte senkrechte Bildhälfte enthält das korrekte Teilbild gem der Größenänderung. Hier hilft kein Schrauben (jedenfalls meins nicht). Ich hab einen grundsätzlichen Fehler drin, den ich nicht erkennen kann. Erst wenn das gelungen ist, kann ich mich der eigentlichen Aufgabe widmen...
...falls ihr nicht weiterhin über meinen Kopf hinweg entscheidet, daß dies eine unwürdige Übung sei. Tut mir leid, ihr habt alle definiv Unrecht: "Hallo World!" war die erste völlig unnötige Übung, die wohl jeder absolviert hat. "Mit den PC kann man Probleme lösen, die man ohne ihn gar nicht hätte!"
Also bitte! Haltet einen User, der zur Runde stößt, um zu üben, um was zu lernen, als allererstes mal für erwachsen! Bitte, es ist unerläßlich notwendig, andernfalls existiert dieses Board gar nicht! Genauso wie die 3 anderen Boards, in denen ich überhaupt kein Echo auf diese Frage bekam. Dabei leben zumindest in einem von ihnen Kenner und API-Kenner von Feinsten, ich hatte die großen, staunenden Augen, als ich deren Werke sah. Hier fühlte ich mich anfangs allerdings spontan zuhause.
void __fastcall TResa::ButtonEnter(TObject *Sender) { // 2 TEdit stellten via OnExit proportionale Koordinaten ein. // Ziel ist ein TImage, welches das veränderte Bild aufnimmt. Ziel->Width = StrToInt(EditX->Text); Ziel->Height = StrToInt(EditY->Text); // Eine Speichergrafik übernimmt das Bild, // nachdem es via Open-Code im TImage Start geöffnet wurde. Graphics::TBitmap* SrcBmp = new Graphics::TBitmap; SrcBmp->Width = Start->Width; SrcBmp->Height = Start->Height; SrcBmp->Assign(Start->Picture->Graphic); // Speichergrafik übernimmt, um völlig separat arbeiten zu können. Graphics::TBitmap *pBitmap = new Graphics::TBitmap(); // Zeichnung direkt in das BitMap-Objekt ausgeben. Byte *ptr; try { pBitmap->Width = SrcBmp->Width; pBitmap->Height = SrcBmp->Height; pBitmap->Assign(Start->Picture->Graphic); for (int y = 0; y <= pBitmap->Height; y++) { ptr = (Byte *)pBitmap->ScanLine[y]; for (int x = 0; x <= pBitmap->Width; x++) ptr[x] = (Byte)y; } pBitmap->Canvas->Draw(0,0,pBitmap); } catch (...) { ShowMessage("Bitmap konnte nicht geladen oder verändert werden"); } delete SrcBmp; SrcBmp = NULL; // eine weitere Speichergrafik stretcht das bearbeitete Bild // in seinen Clientbereich und übergibt an das TImage Ziel. Graphics::TBitmap* DestBmp = new Graphics::TBitmap; DestBmp->Width = Ziel->Width; DestBmp->Height = Ziel->Height; RECT DestRect = Rect(0, 0, Ziel->Width, Ziel->Height); DestBmp->Canvas->StretchDraw(DestRect, pBitmap); Ziel->Picture->Assign(DestBmp); delete pBitmap; pBitmap = NULL; // Nur für die Testphase, übernimmt später eine Save-Routine. Ziel->Picture->SaveToFile("DestBmp.BMP"); delete DestBmp; DestBmp = NULL; }
Kann jemand den Fehler erkennen?
-
Original erstellt von <Omega-X>:
**
...falls ihr nicht weiterhin über meinen Kopf hinweg entscheidet, daß dies eine unwürdige Übung sei. Tut mir leid, ihr habt alle definiv Unrecht: "Hallo World!" war die erste völlig unnötige Übung, die wohl jeder absolviert hat. "Mit den PC kann man Probleme lösen, die man ohne ihn gar nicht hätte!"
**Ich bitte dich! Keiner hat gesagt, dass dich das nicht weiterbringt! Ich habe selbst in Java ein Programm programmiert, mit dem man Bilder sogar auf 4 verschiedene Arten vergrößern und verkleinern kann. Das kann durchaus spannend sein und auch sehr anspruchsvoll. Ich suche immernoch nach einer Methode, das Ergebnis weiter zu verbessern.
-
Erst fand ich es richtig toll, daß man sich Gedanken gemacht hat. Ich geb ja auch am liebsten Hilfe, die auch wirklich nützt. Aber dem Passionisten, was immer dessen Passion sein mag, nicht dem Kommerz.
Notepad hat einfach nur genervt, Freeware wurde gecheckt, nicht glücklich, der eigene gebaut. Ein Mitstreiter hat ihn jetzt auch, er will nichts anderes mehr.
HTML mit kommerziellen Tools? Lieber schrieb ich rein nur im eigenen Notepad, bis ich Weaverslave entdeckte. Es wird nur selten so sein, aber Freie Kreationen können durchaus mehr Spaß machen und nützlicher sein als die teuersten und oft für den Hausgebrauch nutzlos überfrachteten Kommerztools.Na ja, und jetzt hab ich einen klitzekleinen Bedarf, aber wie üblich da, wo die Hilfe aufhört. Das mit den Sternen + viel zu weit kennt man ja. Kann Speicherformat nützen? Das wort steht nur ein einziges mal in der Hilfe, bei TBitmap::PixelFormat. "Mit PixelFormat können Sie das interne Bild des Bitmaps auf ein bestimmtes Speicherformat oder eine bestimmte Farbtiefe setzen..."
Na ist doch schön. Es gibt also Speicherformate, aber nur der Tiegel unter dem Regenbogen weiß, was sie beinhalten. Ähnlich kurzgeschlossen sind auch ScanLine usw. Ich hab nur ein Beispiel, aber der Weg für den Algor gelingt nicht. Was kann ich tun außer Fragen und dabei hoffen? Na ja, und nachdem geklärt ist, wofür ich es brauchen möchte, scheint das Thema nicht mehr zu existieren. Ist doch klar, daß ich estwa trüpselich dasteh.
Das einzige, was ich noch konnte, war die Fehlermeldung rausbringen. Beim Probieren hatte ich einmal die Zuweisung gewechselt, aber vergessen, dann auch für Width und Height die Zuweisung zu ändern.
So, jetzt könnte ich zwar das Bild heller und dunkler machen, dafür hatte ich mal eine Routine für ein Maltool geschrieben. Aber die Aufgabe hat ja nichts mit TColor oder so zu tun. Sie hat mit etwas zu tun, das ich nicht kenne...
-
Oh Mann, und du wirfst anderen "aufgedunsene Sprache" vor!?