[GELÖST] LoadPixmapPNG Bilder maskieren?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] LoadPixmapPNG Bilder maskieren?

BeitragSo, März 11, 2018 23:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich schon wieder Very Happy

Ich beobachte aktuell folgendes Problem: Ich habe ein Bild per SavePixmapPNG() in eine Datei geschrieben. Dieses Bild lade ich bei Programmstart per LoadPixmapPNG() wieder aus der Datei und übergebe das Pixmap-Objekt an LoadImage(). In dem Bild gibt es einen Bereich, der durchsichtig gezeichnet werden soll, dort habe ich die Farbe RGB(255, 0, 255) gemalt. Das Problem ist nun, dass die mit LoadPixmapPNG() geladenen Bilder scheinbar nicht auf die Maskcolor reagieren. Lade ich ein Bild normal mit LoadImage() (Auch PNGs kann ich so laden und diese werden maskiert) und einem festen Pfad ist alles gut, sobald LoadPixmapPNG() aufgerufen wird und aus dem Objekt ein Bild geladen wird, klappt es nicht mehr... Woran könnte das liegen?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Mi, März 14, 2018 18:59, insgesamt einmal bearbeitet

Lobby

BeitragMo, März 12, 2018 10:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Wohl daran, dass die Maskierung von LoadImage durchgeführt wird. LoadPixmapPNG kann das vermutlich schon allein deswegen nicht, damit aus einem 24 Bit Bild kein 32 Bit Bild wird.

Wozu brauchst du die Maskierung in der Pixmap? Und vielleicht interessanter: Warum verwendest du nicht gleich den Alpha-Kanal anstatt eine Farbe zum Maskieren? Was Anderes macht LoadImage intern auch nicht Smile
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux
 

CO2

ehemals "SirMO"

BeitragMo, März 12, 2018 19:24
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Weg ist zugegebenermaßen "wirr": Ich habe ein Spielermodell ursprünglich im BMP-Format gehabt (Deshalb die Maskcolor). Das habe ich zunächst ganz konventionell mit LoadImage geladen und alles war gut. Dann habe ich mir aufgrund von "Datenzusammenführung" gedacht, dass die Information, wo das ImageHandle liegt auch mit zu dem Spielermodell gehört. Ich musste also das BMP umwandeln in eine Datei, in der sowohl Bild- als auch zwei Double-Informationen verhaftet sind. Dies mache ich über einen Converter, welcher das Bild so lädt, wie es ist und mit SavePixmapPNG dann in eine Ausgabedatei schreibt (zusammen mit der Information des Handles). Zum laden lese ich die Datei mit ReadStream aus und lade zunächst eine Pixmap via LoadPixmapPNG(), um anschließend aus der Pixmap das Bild per LoadImage zu laden. Ab diesem Zeitpunkt (oder eventuell schon vorher) greift die Maskcolor dann nicht mehr.
Ich habe das BMP nun in ein PNG umgewandelt und den Alphakanal genutzt, so funktioniert es. Trotzdem würde mich interessieren, warum bei meinem ursprünglichen Vorgehen die Maskcolor nicht greift...
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Lobby

BeitragMo, März 12, 2018 20:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ich mich recht erinnere hat LoadImage for dem Uploaden einfach alle Pixel mit der Farbe der Maske auf Transparent gesetzt. Wie hast du denn deine Pixmap gezeichnet?

BMP solltest du am besten nie verwenden, es hat keine mir bekannten Vorteile (selbst einlesen geht mit PNG in der Regel schneller weil weniger Daten von der Platte gelesen werden müssen).
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux
 

CO2

ehemals "SirMO"

BeitragDi, März 13, 2018 18:55
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe folgendes gemacht:
- Das Bild als .bmp sieht wie folgt aus
user posted image

- Zum Schreiben der Datei BlitzMax: [AUSKLAPPEN]
Local img:TImage = LoadImage("player.bmp")

Local stream:TStream = WriteStream("player.mdl")

WriteDouble(stream, 16)
WriteDouble(stream, 16)

Local pix:TPixmap = LockImage(img)
SavePixmapPNG(pix, stream)
UnlockImage(img)

CloseStream(stream)

End


- Zum laden der Datei BlitzMax: [AUSKLAPPEN]
Graphics(800, 600)
Local FPSLimiter:TTimer = CreateTimer(60)

SetMaskColor(255, 0, 255)

Local model:TStream = ReadStream("player.mdl")
Local hanx:Double = ReadDouble(model)
Local hany:Double = ReadDouble(model)
Local pix:TPixmap = LoadPixmapPNG(model)
CloseStream(model)

Local img:TImage = LoadImage(pix)

SetImageHandle(img, hanx, hany)

Local rot:Double = 0

Repeat
WaitTimer(FPSLimiter)
Cls()

SetRotation(rot)
DrawImage(img, 100, 100)

rot = (rot + 0.5) Mod 360

Flip(0)
Until KeyHit(KEY_ESCAPE)
End


- Das Resultat ist anschließend folgendes:
user posted image

Die Maskcolor habe ich vor dem Laden des Bildes gesetzt, auch die explizite Angabe, dass es sich um ein MASKEDIMAGE handelt, ergibt keinen Unterschied.

Ich habe das Spielermodell (und alle anderen betreffenden Bilder) auf PNG umgestellt, die Nutzung des Alphakanals schafft - wie geschrieben - Abhilfe. BMP ist bei mir irgendwie so drin, wenn ich ein Bild für ein Spiel male, wird das als erstes im BMP-Format gespeichert... Das werde ich dann in Zukunft nicht mehr tun, die Vorteile waren mir gar nicht so klar. Very Happy
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Lobby

BeitragDi, März 13, 2018 20:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Hab mir mal den zugrunde liegenden Code von LoadImage angesehen (findet man alles bequem auf GitHub). Wenn eine Pixmap angegeben wird, verwendet LoadImage diese einfach als interne Pixmap. Falls ein Dateipfad angegeben wird, lädt er eine Pixmap aus diesem Pfad. Der entscheidende Code für die Maskierung ist dieser hier (eine Methode von TImage, die von TImage.Load aufgerufen wird):
BlitzMax: [AUSKLAPPEN]
Method SetPixmap( index,pixmap:TPixmap )
If (flags & MASKEDIMAGE) And AlphaBitsPerPixel[pixmap.format]=0
pixmap=MaskPixmap( pixmap,mask_r,mask_g,mask_b )
EndIf
pixmaps[index]=pixmap
seqs[index]=0
frames[index]=Null
End Method

Die besagt, dass nur maskiert wird, wenn die Pixmap noch keinen Alpha-Kanal hat. Deine gespeicherte Pixmap hat aber einen Alphakanal, denn das LoadImage aus deinem Code zum Schreiben maskiert bereits eine Farbe aus der Bitmap, und zwar schwarz Twisted Evil (so zumindest lese ich den Code)

Die einfachste Lösung wäre wohl, bereits in deinem schreibenden Programm die MaskColor auf 255,0,255 zu setzen, um dann im lesenden Programm darauf zu verzichten.
TheoTown - Eine Stadtaufbausimulation für Android, iOS, Windows, Mac OS und Linux
 

CO2

ehemals "SirMO"

BeitragMi, März 14, 2018 18:58
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, wenn ich im schreibenden Programm die Maskcolor entsprechend setze, funktioniert es, auch wenn im lesenden Programm nochmal die Maskcolor gesetzt wird...

Ich "tagge" diesen Thread mal als [GELÖST], die ursprüngliche Frage wurde ja geklärt.

Danke Dir Wink
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

soli

BeitragMo, Apr 01, 2019 23:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist zwar lange her, aber in einem englischen Forum wurde ganz gut erklärt warum das so ist.
Vielleicht nutzt es jemand.

https://www.syntaxbomb.com/index.php?topic=4182.0
Zitat:
SetBlend SOLIDBLEND
before anything you do not want to have transparency

SetBlend MASKBLEND
before anything in which you want pixels either 100% or completely transparent (must have alpha channel, or be loaded with SetMaskColor() first)

SetBlend ALPHABLEND
Before anything with an alpha channel from 0 through 255 determines the amount of transparency. Equivalent to MASKBLEND if the alpha channel contains only 0 or 255.

SetBlend LIGHTBLEND
Will add the pixels of the image to the pixels of the backbuffer, creating a lighting effect

SetBlend SHADEBLEND
Will multiply the pixels with the backbuffer to cause a shading effect.

Note that SetMaskColor() does not work the way you might think it does. BlitzMax does not use mask colors while drawing images, it only uses the alpha channel. SetMaskColor() just tells BlitzMax that while loading any image without an alpha channel, create one and check to see if the pixel color equals the mask color. If it does, then set the image's alpha for that pixel to 0, otherwise set it to 255. This happens at load time, so it will not have any affect on images previously loaded. It also has no affect on images that already have an alpha channel.

So to summarize: The equivalent of DrawBlock is
SetBlend SOLIDBLEND
DrawImage Image,x,y

The equivalent of early blitz DrawImage is
SetBlend ALPHABLEND 'or SetBlend MASKBLEND
DrawImage Image,x,y

Note also that BlitzMax SetMaskColor defaults to 0,0,0. So if your mask color is black, no need to call SetMaskColor first. Also SetBlend ALPHABLEND is default, so if you are loading only images that have an alpha channel already, no need to call that. When you call either of those commands, the state remains the same until you call the command again, so you only need to call them once and not worry about it again until you need to change it.
solitaire

bmurray

BeitragFr, Dez 18, 2020 10:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

ich kapere mal diesen Thread für meine Frage. Ich habe das mit transparanten PNGs und dem Alphachannel immer noch nicht verstanden.

Ich lade eine PNG mit transparentem Hintergrund über LoadImage (ohne Flags) und zeichne sie über DrawImage. Wenn das Bild aber nun gezeichnet wird, werden alle schwarzen Pixel transparent. Wenn ich nun zum Beispiel SetMaskColor auf (255,0,255) stelle (rosa), bevor ich das Bild lade, dann werden dennoch alle schwarzen Pixel transparent. Ich kann bei SetMasKColor eingeben, was ich will, die schwarzen Pixel werden immer transparent gezeichnet. Ich habe auch verschiedene Flags bei LoadImage ausprobiert, alle das gleiche Ergebnis. Mit SetBlend habe ich auch schon alles probiert, immer das selbe Resultat.

Zitat:
So to summarize: The equivalent of DrawBlock is
SetBlend SOLIDBLEND
DrawImage Image,x,y


Das funktioniert leider gar nicht, weil dann alle Bilder und Texte nur rieisge Pixelklumpen werden.

Ich möchte einfach nur ein PNG zeichnen lassen mit allen Pixeln, und nur dasjenige soll transparent gezeichnet werden, was bereits in der PNG transparent ist (wie es DrawBlock in Blitz Plus gemacht hat). Ist das irgendwie möglich?

Thunder

BeitragFr, Dez 18, 2020 19:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe gerade ein altes Projekt von mir heruntergeladen und angesehen. Ich habe das früher so gemacht:

BlitzMax: [AUSKLAPPEN]
AppTitle="Dump Box"
Graphics GW, GH
SetBlend ALPHABLEND ' direkt nach Graphics


Meistens ALPHABLEND, weil es auch Transparenz kann. Dann vor jedem DrawImage sicherstellen, dass die Color weiß ist. Also im Zweifel:

BlitzMax: [AUSKLAPPEN]
SetColor 255,255,255 ' vor DrawImage
DrawImage gfx,zentral_x+src_x*FELD_BREITE,zentral_y+src_y*FELD_BREITE,9


weil sich sonst die Farbe irgendwie auf das Bild auswirkt.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

bmurray

BeitragSa, Dez 19, 2020 14:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke Dir, aber leider funktioniert auch das nicht. In den englischen Foren sind die Leute aber auch recht ratlos, wie mir scheint

Xeres

Moderator

BeitragSa, Dez 19, 2020 14:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn ALPHABLEND nicht hilft hat dein PNG vielleicht gar keinen Alpha Channel? Funktioniert bei mir auf jeden Fall noch.

Edit:
BlitzMax: [AUSKLAPPEN]
Graphics(256, 256, 0, 60)
SetClsColor(0, 200, 0)
Cls

SetColor(255, 255, 255)
SetBlend(ALPHABLEND)
DrawImage(LoadImage("AimCross.png"), 0, 0)

Flip
WaitKey
End

mit AimCross.png => Ergebnis

Thunder

BeitragSa, Dez 19, 2020 22:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Welche BlitzMax-Version verwendest du? Hast du schon die verschiedenen Grafiktreiber durchprobiert, DX7, DX9, GL?
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

bmurray

BeitragSo, Dez 20, 2020 13:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, das war fies! Es lag an der Datei. Ja, sie hatte einen Alphakanal. Also hab ich einfach in der Datei mit schwarzer Farbe rumgemalt, was dann eben nicht transparent gemacht wurde, die anderen schwarzen Pixel aber weiterhin schon. Ich kenn mich mit Bilddateien nicht gut genug aus, aber kann es sein, dass auch Farbpixel als "Alphakanal" gespeichert werden können? Also dass schwarze Pixel eben auch unter diesem Attriubut gespeichert werden? Nur so kann ich es mir erklären, dass er die schwarzen Pixel eben doch transparent gemacht hat.

Xeres

Moderator

BeitragSo, Dez 20, 2020 21:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn es einen Alphakanal gibt, werden eigentlich vier bytes per pixel gespeichert: ARGB. Du kannst Pixel haben die schwarz und transparent sind #00000000, Pixel die schwarz und voll sichtbar sind #FF000000 und jede Kombination dazwischen. Es liegt ganz am Grafikprogramm wie mit der Transparenz umgegangen wird.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

bmurray

BeitragMo, Dez 21, 2020 0:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke! Klingt logisch

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group