Toon posts:

[C#.NET] Floodfill, waar is-ie?

Pagina: 1
Acties:
  • 113 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik zoek een functie om in een bitmap een bepaald gebied (aangesloten pixels van dezelfde kleur) in te kleuren met een andere kleur. Ik kan het maar niet vinden tussen de vele graphics routines. Natuurlijk kan ik wel zelf een functie maken die alle aangesloten pixels scant, maar dat lijkt me niet de snelste oplossing.

  • kvdveer
  • Registratie: November 2000
  • Laatst online: 06-11-2025

kvdveer

Z.O.Z.

Welke taal? De meeste talen bevatten wel zoiets. Heet doorgaans fill of zo.

edit:
Sorry. titel niet gelezen

[ Voor 26% gewijzigd door kvdveer op 26-11-2002 15:20 . Reden: typo ]

Localhost, sweet localhost


Verwijderd

in de GDI namespace moet je zijn. (System.Drawing)

ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemDrawingGraphicsClassFillRectangleTopic.htm

gevonden in 7 seconden.

Verwijderd

Alleen wil ie geen vierkantje vullen? maar 'n floodfill doen/

Verwijderd

Topicstarter
Dat is FillRectangle (kleurt een rechthoek).
Er staat niet bij hoe je een willekeurig gebied (aangesloten pixels) inkleurt.

Misschien kun je de 7 seconden beter besteden aan het lezen van mijn vraag?

  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
Gebruik Graphics.FillPath of Graphics.FillRegion om een willekeurig gebied te vullen.

[ Voor 7% gewijzigd door TlighT op 26-11-2002 15:44 ]


  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Het moet in ieder geval met een FillRegion of FillPath... GDI+ heeft geen FloodFill in tegenstelling tot GDI.
http://www.dotnet247.com/247reference/msgs/5/26463.aspx

[ Voor 3% gewijzigd door alley op 26-11-2002 15:45 ]

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


Verwijderd

met fillRectangle kun je ook een gebiedje vullen met een kleur. Ik gaf dat voorbeeld om aan te geven waar hij moet kijken, er staan een aantal fill* methods gelist bij de Graphics class in System.Drawing. Aaneengesloten pixels vormen at most 3 rechthoeken.

En verder, meneer WhizzVin, als JIJ eens de moeite had genomen eens in de reference te duiken van .NET, had je, wanneer je had gekeken naar de class waarnaar ik verwees, kunnen zien dat daar de fill methods in staan die je wilt. Ik begrijp het gezemel overigens niet over floodfill en GDI+, we praten toch niet over een VESA buffertje dat gecleared moet worden, of begrijp ik het verkeerd?

Verwijderd

Topicstarter
Ik heb heel goed gekeken bij alle fill* methodes. En snap nog steeds niet wat jij bedoelt. Bijvoorbeeld: "Aaneengesloten pixels vormen at most 3 rechthoeken." Waar slaat dit op? Deel eens een ellips op in 3 rechthoeken...

Ik leg het wel nog een keer uit. Neem bijvoorbeeld een bitmap: een rode figuur op een blauwe achtergrond. Nu wil ik de achtergrond groen maken. Maar binnen de rode figuur kunnen ook blauwe pixels zijn, die moeten blauw blijven. Dus ik wil graag een functie: bmp.fill(0,0,green) of iets dergelijks zodat de correcte pixels groen worden... snappie? :)

Wat TlighT zei: "Gebruik Graphics.FillPath of Graphics.FillRegion om een willekeurig gebied te vullen.": dit werkt wel, maar dan moet je eerst een Path of Region definieren. En dat heb ik zo niet bij de hand. Dus ik denk dat ik het maar anders ga doen (of zelf schrijven of anders aanpakken).

[ Voor 22% gewijzigd door Verwijderd op 26-11-2002 16:50 ]


Verwijderd

Verwijderd schreef op 26 November 2002 @ 16:47:
Ik heb heel goed gekeken bij alle fill* methodes. En snap nog steeds niet wat jij bedoelt. Bijvoorbeeld: "Aaneengesloten pixels vormen at most 3 rechthoeken." Waar slaat dit op? Deel eens een ellips op in 3 rechthoeken...
Dat zijn geen aaneengesloten pixels (als je dat rechttoerechtaan zou fillen, moet je pixels skippen). Aaneengesloten pixels beslaan dus behalve de bovenste en onderste regel een rechthoek met de volle breedte van de bitmap. Daarnaasts dus de bovenste en de onderste regel.
Ik leg het wel nog een keer uit. Neem bijvoorbeeld een bitmap: een rode figuur op een blauwe achtergrond. Nu wil ik de achtergrond groen maken. Maar binnen de rode figuur kunnen ook blauwe pixels zijn, die moeten blauw blijven. Dus ik wil graag een functie: bmp.fill(0,0,green) of iets dergelijks zodat de correcte pixels groen worden... snappie? :)
Ja snap ik, maar hoe wil jij bij een functie opgeven: 'fill area enne alleen deze en deze pixels' zonder areadefinitie? Wat jij wilt is een samengestelde bitmap fillen terwijl je eigenlijk 1 of meerdere delen wilt fillen en daarna die blenden tot de resultbitmap. 2 kleuren bitmap is dan nog wel te doen, maar een 24 bpp bitmap is met een functie zoals jij die voorstelt niet te fillen, je kunt zonder areaspecificatie niet alle kleuren opgeven die je wilt vullen. Als je 1 kleur wilt wijzigen in een andere, waarom neem je dan geen indexed color bitmaps? (256kleur)? Je wijzigt dekleur in het colorregister en klaar.
Wat TlighT zei: "Gebruik Graphics.FillPath of Graphics.FillRegion om een willekeurig gebied te vullen.": dit werkt wel, maar dan moet je eerst een Path of Region definieren. En dat heb ik zo niet bij de hand. Dus ik denk dat ik het maar anders ga doen (of zelf schrijven of anders aanpakken).
Mja, het is me volkomen onduidelijk waarom je uberhaupt zou willen wat jij zou willen, en ik kan me ook niet aan de indruk onttrekken dat zo'n floodfill functie ook niet bestaat, behalve bij bitlayer based systemen zoals de amiga.

  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Verwijderd schreef op 26 november 2002 @ 18:45:
Mja, het is me volkomen onduidelijk waarom je uberhaupt zou willen wat jij zou willen, en ik kan me ook niet aan de indruk onttrekken dat zo'n floodfill functie ook niet bestaat, behalve bij bitlayer based systemen zoals de amiga.
GDI (zonder de plus) heeft wel een floodfill hoor, die doet precies wat WhizzVin wil.. dus het bestaat zeker

[ Voor 5% gewijzigd door alley op 26-11-2002 20:03 ]

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


Verwijderd

Topicstarter
Verwijderd schreef op 26 November 2002 @ 18:45:

Ja snap ik, maar hoe wil jij bij een functie opgeven: 'fill area enne alleen deze en deze pixels' zonder areadefinitie?
Ken je Paint nog? De 4e knop van boven is 'Fill with color' als je die aanklikt krijg je een emmer te zien. Dan kun je op een bepaalde plaats een gebied inkleuren. Dat gebied is gedefinieerd als alle pixels met exact dezelfde kleur (kan ook in 24 bits bitmap), die bovendien in een aangesloten gebied ligt.
Wat jij wilt is een samengestelde bitmap fillen terwijl je eigenlijk 1 of meerderdelen wilt fillen en daarna die blenden tot de resultbitmap. 2 kleuren bitmap is dan nog wel te doen, maar een 24 bpp bitmap is met een functie zoals jij die voorstelt niet te fillen, je kunt zonder areaspecificatie niet alle kleuren opgeven die je wilt vullen. Als je 1 kleur wilt wijzigen in een andere, waarom neem je dan geen indexed color bitmaps? (256kleur)? Je wijzigt dekleur in het colorregister en klaar.
Ik hoef maar 1 kleur te fillen. De grens van het gebied wordt gevormd door alle pixels met een andere kleur dan die van de gekozen pixel.

Als er meerdere losse gebieden ontstaan met dezelfde kleur, dan wordt het gebied genomen waar de gekozen pixel in ligt.
Mja, het is me volkomen onduidelijk waarom je uberhaupt zou willen wat jij zou willen, en ik kan me ook niet aan de indruk onttrekken dat zo'n floodfill functie ook niet bestaat, behalve bij bitlayer based systemen zoals de amiga.
Ik heb een paar tekeningen in bitmaps. Nou wil ik graag de bitmaps op een image tekenen. Maar het moet niet als een wit vierkant met plaatje erin worden getekend, maar alleen het plaatje zelf (zonder wit eromheen) moet op de image komen. En het wit dat IN het plaatje zit moet wit blijven en niet transparant. Dus wou ik bmp.floodfill(0,0,color.transparant) gebruiken o.i.d.

Verwijderd

Ah, die feature. Ik ken GDI te slecht om te weten dat die bestond in GDI. Maar die floodfill is niet helemaal wat whizzwin wil, want ik begreep dat whizzwin in een totale bitmap alle pixels van een kleur wil vervangen door een andere kleur, en niet binnen een gebied wat de GDI floodfill in 'paint' wel doet. (of photoshop)

Als het niet realtime moet, zou ik fijn zelf in een 3 regelige forloop de pixels afsjouwen. Waarschijnlijk was je al klaargeweest.

  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

Verwijderd schreef op 27 november 2002 @ 08:32:
Ah, die feature. Ik ken GDI te slecht om te weten dat die bestond in GDI. Maar die floodfill is niet helemaal wat whizzwin wil, want ik begreep dat whizzwin in een totale bitmap alle pixels van een kleur wil vervangen door een andere kleur, en niet binnen een gebied wat de GDI floodfill in 'paint' wel doet. (of photoshop)

Als het niet realtime moet, zou ik fijn zelf in een 3 regelige forloop de pixels afsjouwen. Waarschijnlijk was je al klaargeweest.
Nee hoor, de floodfill in GDI doet alleen aaneensluitende kleuren, dus als ie een vlak met andere kleur tegenkomt, slaat ie alle kleuren binnen dit vlak over, ook al staan er pixels met dezefde kleur als de area waar een floodfill op gebeurt.... precies wat whizzwin wil....

Maar goed, we raken offtopic :) want de vraag is hoe het in GDI+ moet

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


  • TlighT
  • Registratie: Mei 2000
  • Laatst online: 22-03 10:40
alley schreef op 27 november 2002 @ 10:17:
[...]
Maar goed, we raken offtopic :) want de vraag is hoe het in GDI+ moet
Hoe dat in GDI+ moet staat in dat linkje wat je gisteren gepost hebt:
GdiPlus does not implement a FloodFill type of operation.

However, using LockBits() on an Bitmap you could access the raster data of
the bitmap and you could implement your own FloodFill by reading and
writting the pixels directly.

Verwijderd

alley schreef op 27 november 2002 @ 10:17:
[...]
Nee hoor, de floodfill in GDI doet alleen aaneensluitende kleuren, dus als ie een vlak met andere kleur tegenkomt, slaat ie alle kleuren binnen dit vlak over, ook al staan er pixels met dezefde kleur als de area waar een floodfill op gebeurt.... precies wat whizzwin wil....
Nee dat is niet wat whizzwin wil. Hij wil bv alle blauwe pixels groen hebben, en stel je hebt 3 elipsen met blauwe pixels in een verder rood plaatje. Als je dan volgens jou de floodfill zou aanroepen op het gehele plaatje startend in 1 van de blauwe elipsen, zou je slechts 1 blauwe elips groen gefilled krijgen. Hij wil gewoon een floodfill op de complete bitmap doen en alle blauwe pixels door groen vervangen, dus dat alle 3 de elipsen worden vervangen door groene pixels. Dat is wat ik ervan begreep. En dat doe je volgens mij door alle pixels te examinen.

[edit]
Ik begreep het verkeerd, hij wil idd maar 1 area vullen, dus 1 elips per keer.

[ Voor 6% gewijzigd door Verwijderd op 27-11-2002 10:33 ]


Verwijderd

Topicstarter
Argh! Als je mijn reply's iets nauwkeuriger leest staat er toch duidelijk dat ik precies Floodfill wil doen. Dus alleen de pixels in een enkel gebied moeten worden verkleurd, zoals iedereen behalve Otis ook weet.

Het werkt natuurlijk wel met direct pixel access en een flood functie, maar ik vroeg me alleen af of er al een functie voor bestond. Die is er dus niet in GDI+ (en daarmee is mijn vraag beantwoord).

Nu probeer ik trouwens iets anders: de bitmaps transparant maken met de alpha channel. Het leuke is dat je dan ook half-doorzichtige gebieden kunt maken (kan in bijv. Photoshop). Maar als je een bitmap laadt, dan wordt de alpha kanaal blijkbaar niet mee geladen.

code:
1
Bitmap im = (Bitmap)rm.GetObject("AlphaTest");


AlphaTest is een bitmap (met alpha channel) in de resourcemanager rm. Maar de alpha channel wordt blijkbaar niet mee geladen want als ik de bitmap teken, wordt de achtergrond volledig overgeschreven.

Ik ga het zo proberen met een RAW image ipv bitmap. Ik zou graag willen weten hoe dat het eenvoudigst in een bitmap kan worden geladen. De RAW bestand bestaat uit RGBA bytes (32 bit per pixels) terwijl een GDI+ bitmap het formaat ARGB heeft. Het lukt wel om de pixels een voor een in te lezen en de channels goed te zetten, maar dan moet je weer 100000-en iteraties doen per bitmap terwijl LoadImage waarschijnlijk veel sneller werkt.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 27 November 2002 @ 08:32:
Ah, die feature. Ik ken GDI te slecht om te weten dat die bestond in GDI. Maar die floodfill is niet helemaal wat whizzwin wil, want ik begreep dat whizzwin in een totale bitmap alle pixels van een kleur wil vervangen door een andere kleur, en niet binnen een gebied wat de GDI floodfill in 'paint' wel doet. (of photoshop)
Ik wil niet moeilijk doen Otis maar ik vind je replies in dit topic redelijk nutteloos en erg lomp. Je hebt z'n vraag duidelijk niet begrepen en zoals je zelf aangeeft weinig kennis van de gevraagde materie, en zit 'm wel af te zeiken met dat z'n vraag met de search zo gevonden zou zijn: alleen kom jij met die search ook met de verkeerde antwoorden. Als oplossing draag je vervolgens aan:
Als het niet realtime moet, zou ik fijn zelf in een 3 regelige forloop de pixels afsjouwen. Waarschijnlijk was je al klaargeweest.
Terwijl Whizzvin in z'n openingspost zegt:
Natuurlijk kan ik wel zelf een functie maken die alle aangesloten pixels scant, maar dat lijkt me niet de snelste oplossing.
Hier heeft ie gelijk in, daar SetPixel en GetPixel niet de snelste routines zijn om 3000 keer te gebruiken in vergelijking met een dedicated API-routine. De FloodFill functie is er niet voor niets in GDI.

Nofi, ik stel je bijdragen hier op het forum gewoonlijk erg op prijs maar hier stond je zonder voldoende onderbouwing wel heel snel op je achterpoten te steigeren.

Professionele website nodig?


Verwijderd

curry684 schreef op 27 november 2002 @ 11:23:
[...]
Ik wil niet moeilijk doen Otis maar ik vind je replies in dit topic redelijk nutteloos en erg lomp. Je hebt z'n vraag duidelijk niet begrepen en zoals je zelf aangeeft weinig kennis van de gevraagde materie, en zit 'm wel af te zeiken met dat z'n vraag met de search zo gevonden zou zijn: alleen kom jij met die search ook met de verkeerde antwoorden. Als oplossing draag je vervolgens aan:
HO! Ik heb wel degelijk veel ervaring in pixelbased graphics manipulatie! Ik kende de gdi floodfil functie niet, maar ik ken .NET wel van haver tot gort zo langzamerhand, en met de functionaliteit die hij wilde kan ik toch een functie suggereren? In zijn openingspost legt hij niet uit wat de floodfill doet, maar komt met de opmerking 'aaneengesloten pixels'. In gfx manipulatie routines werk je per row, dus in feite zijn alle pixels in een 1dimensionaal array opgeslagen. Als je praat over 'aaneengesloten pixels' praat je dus over aaneengesloten pixels in een 1 dim. array. IEDER andere set pixels is niet aaneengesloten en moet je aanspreken met een delta.

Ik roep: kijk eens in de graphics class in .net, fill routines zat, moet genoeg zijn voor wat je wilt, reageert hij met 'of ik die 7 seconden wil gebruiken voor het lezen van zn vraag'. Ja no offence, maar dat is wel vriendelijk oid? Wellicht moet meneertje whizzkid eens leren zn vraag beter te formuleren.
[...]

Terwijl Whizzvin in z'n openingspost zegt:
[...]
Hier heeft ie gelijk in, daar SetPixel en GetPixel niet de snelste routines zijn om 3000 keer te gebruiken in vergelijking met een dedicated API-routine. De FloodFill functie is er niet voor niets in GDI.
Wat is er mis met het converteren van de bitmap naar een bytearray en een setje longword manipulatie routinetjes van 1 regel elk? NIEMAND praat over get/set pixel. Wat er niet voor niets of wel voor niets in GDI zit zal me worst zijn eerlijk gezegd. De meeste canvas routines van de GDI zijn nauw verwant aan de SH*library van IE, dus over 'general' GDI praten lukt uberhaupt niet. (ooit een jpg plaatje ingeladen in C++ met de general GDI functies en bewerkt als bitmap? Denk het niet)

Kennelijk heeft System.Drawing's Graphics class geen floodfill routine, maar is met wat kleine routines het makkelijk te bouwen. Echter de topicstarter wil per se een routine die floodfill doet en wil zelf niet nadenken, nou kereltje, dan zoek je het toch fijn zelf uit! Ik zal nog eens iemand proberen te helpen met .NET hier! Wellicht niet in jouw noch meneer whizzkid^H^H^Hwin 's hoofd opgekomen, maar ik heb wel moeite gedaan het op te zoeken (kostte wel erg weinig moeite, maar toch).
Nofi, ik stel je bijdragen hier op het forum gewoonlijk erg op prijs maar hier stond je zonder voldoende onderbouwing wel heel snel op je achterpoten te steigeren.
het zal wel... lees meneertje whizzkid's reactie eens op mijn '7 seconden'. Hij weet niet eens wat 'aaneengesloten pixels' inhoudt. Misschien moet whizzwin eerst eens met OpenPTC gaan werken, kan hij leren hoe hij pixels moet manipuleren.

Verwijderd

Verwijderd schreef op 27 november 2002 @ 11:14:
Argh! Als je mijn reply's iets nauwkeuriger leest staat er toch duidelijk dat ik precies Floodfill wil doen. Dus alleen de pixels in een enkel gebied moeten worden verkleurd, zoals iedereen behalve Otis ook weet.
Jaja. Maar dat zijn geen 'aaneengesloten pixels'. Pixelmanipulatie doe je in een 1 dim array, niet in een 2 dim plaatje, tenzij je anti-aliassing wilt doen, maar daar had je het niet over, vandaar datik het verkeerd begreep.
Het werkt natuurlijk wel met direct pixel access en een flood functie, maar ik vroeg me alleen af of er al een functie voor bestond. Die is er dus niet in GDI+ (en daarmee is mijn vraag beantwoord).
Wellicht wel in GDI+ maar niet in System.Drawing. Roep je toch via COM de SH* components aan en ga je daar toch fijn met floodfillen? Of je gaat toch fijn een bitmaparray maken van bytes en met simpele routinetjes je fillroutine bouwen? de .NET lib is ook geschreven in C#, dus trager zal het niet worden. Oh, en win2k/xp bevatten nog steeds de generic GDI routines. Je kunt dus middels de DC en de HWND wel proberen ze aan te roepen.
Nu probeer ik trouwens iets anders: de bitmaps transparant maken met de alpha channel. Het leuke is dat je dan ook half-doorzichtige gebieden kunt maken (kan in bijv. Photoshop). Maar als je een bitmap laadt, dan wordt de alpha kanaal blijkbaar niet mee geladen.
Wat voor bitmap laadt je? Een TGA? Of een bitmap zonder alphachannel zoals BMP of JPG.
code:
1
Bitmap im = (Bitmap)rm.GetObject("AlphaTest");

AlphaTest is een bitmap (met alpha channel) in de resourcemanager rm. Maar de alpha channel wordt blijkbaar niet mee geladen want als ik de bitmap teken, wordt de achtergrond volledig overgeschreven.
HOE teken je? MIddels blending? Of kletter je de bitmap zo op het scherm?
Ik ga het zo proberen met een RAW image ipv bitmap. Ik zou graag willen weten hoe dat het eenvoudigst in een bitmap kan worden geladen. De RAW bestand bestaat uit RGBA bytes (32 bit per pixels) terwijl een GDI+ bitmap het formaat ARGB heeft. Het lukt wel om de pixels een voor een in te lezen en de channels goed te zetten, maar dan moet je weer 100000-en iteraties doen per bitmap terwijl LoadImage waarschijnlijk veel sneller werkt.
LoadImage?

Via .NET's Bitmap class kun je de image inladen, middels lockbits krijg je de bitdata, middels Scan0 krijg je een intptr naar de eerste pixel, middels de stride en de width/height kun je de complete bitmap bereiken, dus alle pixels. Alle bitmaps in core zijn in hetzelfde format, dus als .net / win32 een jpg, tga, bmp of gif laadt, converteert hij deze altijd naar hetzelfde format intern, wat je kunt bereiken mbv die Scan0.

Zie voor transparent drawing de MakeTransparent method, maar dat had je UITERAARD allang bekeken.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 27 november 2002 @ 12:19:
Ik roep: kijk eens in de graphics class in .net, fill routines zat, moet genoeg zijn voor wat je wilt, reageert hij met 'of ik die 7 seconden wil gebruiken voor het lezen van zn vraag'. Ja no offence, maar dat is wel vriendelijk oid? Wellicht moet meneertje whizzkid eens leren zn vraag beter te formuleren.
Jij lokte zelf met de toon van je eerste reply de respons uit, dan moet je niet klagen als er op gehapt wordt en jij op je fout wordt gewezen. Verder zou ik gewoon graag zien dat je je discussies wat minder hooghartig opbouwt en simpelweg al of niet probeert hulp te geven.

Verder heb ik weinig zin in een flamewar hier in dit topic, voor verdere discussie hierover ben ik via mail bereikbaar. Back on-topic dus:
Verwijderd schreef op 27 november 2002 @ 11:14:
Nu probeer ik trouwens iets anders: de bitmaps transparant maken met de alpha channel. Het leuke is dat je dan ook half-doorzichtige gebieden kunt maken (kan in bijv. Photoshop). Maar als je een bitmap laadt, dan wordt de alpha kanaal blijkbaar niet mee geladen.
BMP's ondersteunen per definitie geen alpha-channels: tis een bestandsformaat dat rond 1990 van OS/2 is gejat en loopt dus wat achter hier en daar. Het zou wel erin gebouwd kunnen worden maar hier heeft MS voorlopig niet echt concrete plannen getoond. Je kunt dmv verschillende Raster Operations (ROP's) wel eerst de alphachannel masken en vervolgens het non-transparent plaatje erin kopieren.

Professionele website nodig?


Verwijderd

Topicstarter
Wat voor bitmap laadt je? Een TGA? Of een bitmap zonder alphachannel zoals BMP of JPG.
Ik probeerde eerst BMP (met alphachannel, dus RGBA formaat), maar de alpha laadt-ie dus niet.

Edit1:
Net probeerde ik een TGA te laden (ook met alpha channel), maar ik krijg steeds een OutOfMemory exception :(
Zowel Alpha.bmp als Alpha.tga zijn 40 KB groot en bevatten 100x100x32bit met wat header info. En ik heb minstens 50 MB geheugen vrij.
Edit3: --> TGA format wordt niet ondersteund in Visual Studio.NET, wat deze exceptie veroorzaakt.
Ik probeer nog wel wat andere formaten uit met alpha support.

Edit2:
Het TIFF formaat deed het BIJNA goed. Sommige delen van het plaatje waren transparant, maar er zitten strepen enzo op, alsof het TIFF bestand corrupt was. Maar in een ander tekenprogramma werd het TIFF bestand wel goed geladen. Iemand een idee welk formaat met alpha channel correct wordt gelezen met Image.FromFile("Alpha.***")? Of is RAW data lezen de enige mogelijkheid.

Edit4:
Het PNG formaat heeft gewonnen! Dit is blijkbaar het enige formaat dat de transparantie kan opslaan EN correct wordt ingelezen door Image.FromFile().
HOE teken je? MIddels blending? Of kletter je de bitmap zo op het scherm?
Blending wordt al automatisch gedaan door C#.NET. Werkt goed :) Ik gebruik gewoon g.DrawImage(bmp,...) met bmp = bitmap in ARGB formaat (en g = graphics van image).
Zie voor transparent drawing de MakeTransparent method, maar dat had je UITERAARD allang bekeken.
Inderdaad heb ik dit heel goed bekeken. Maar dit is volgens mij alleen voor als je 1 kleur transparant wil maken (en geen blending gebruikt). Als je bitmaps met alpha kanaal gaat tekenen (DrawImage(bmp,...)) dan worden de kleuren blijkbaar al correct geblend.
Via .NET's Bitmap class kun je de image inladen, middels lockbits krijg je de bitdata, middels Scan0 krijg je een intptr naar de eerste pixel, middels de stride en de width/height kun je de complete bitmap bereiken, dus alle pixels. Alle bitmaps in core zijn in hetzelfde format, dus als .net / win32 een jpg, tga, bmp of gif laadt, converteert hij deze altijd naar hetzelfde format intern, wat je kunt bereiken mbv die Scan0.
Ja, dit is handig! Ik probeer nu een RAW image (100x100x32 bit) uit de resources direct in de bitmap array te laden met een bepaalde constructor van Bitmap. Als het lukt dan is de alpha channel meteen ook geladen, maar ik moet nog even een NullPointerException oplossen. En als de channels verkeerd om zitten (RGBA ipv ARGB) gebruik ik ColorMatrix wel voor de transformatie. Werkt wel sneller dan stap-voor-stap 40000 bytes opschuiven :)

Edit4:
Het is inmiddels gelukt om een PNG plaatje te laden met alpha data en op een image te blenden.
Ik vraag me nog wel af waarom het volgende niet werkt en hoe het wel moet:
code:
1
2
3
4
Byte[] data = (Byte[])(rm.GetObject("Alpha.raw"));
System.IntPtr k = new System.IntPtr(data[0]);
Bitmap si = new Bitmap(10,10,4,System.Drawing.Imaging.PixelFormat.Format32bppArgb,k);
pg2.DrawImage(si,0,0);

Er ontstaat dan ene NullPointerException bij het uitvoeren van de laatste regel.

[ Voor 33% gewijzigd door Verwijderd op 27-11-2002 14:14 ]


Verwijderd

Verwijderd schreef op 27 November 2002 @ 13:35:
[...]
Ik probeerde eerst BMP (met alphachannel, dus RGBA formaat), maar de alpha laadt-ie dus niet.
Die 'A' in BMP is een wassenneus. BMP kun je nl. nooit opslaan in 32 bpp, maar altijd in 24bpp of kleiner.
Edit1:
Net probeerde ik een TGA te laden (ook met alpha channel), maar ik krijg steeds een OutOfMemory exception :(
Zowel Alpha.bmp als Alpha.tga zijn 40 KB groot en bevatten 100x100x32bit met wat header info. En ik heb minstens 50 MB geheugen vrij.
Edit3: --> TGA format wordt niet ondersteund in Visual Studio.NET, wat deze exceptie veroorzaakt.
TGA is een heel simpel format, je zou zelf een reader kunnen bouwen. Je kunt TGA's makkelijk maken in photoshop, dus wellicht een optie. Op dit forum zijn een aantal TGA readers in C++ langsgekomen, dus met een search zijn die wel naar voren te toveren en die source moet makkelijk te porten zijn
[...]
Inderdaad heb ik dit heel goed bekeken. Maar dit is volgens mij alleen voor als je 1 kleur transparant wil maken (en geen blending gebruikt). Als je bitmaps met alpha kanaal gaat tekenen (DrawImage(bmp,...)) dan worden de kleuren blijkbaar al correct geblend.
Ik hoop het voor je, maar zou er niet altijd op vertrouwen. Dit zal alleen goed werken onder XP, windows 98 / ME hebben vziw wel .NET ondersteuning maar geen alphablending in de GDI layer.
[...]
Ja, dit is handig! Ik probeer nu een RAW image (100x100x32 bit) uit de resources direct in de bitmap array te laden met een bepaalde constructor van Bitmap. Als het lukt dan is de alpha channel meteen ook geladen, maar ik moet nog even een NullPointerException oplossen. En als de channels verkeerd om zitten (RGBA ipv ARGB) gebruik ik ColorMatrix wel voor de transformatie. Werkt wel sneller dan stap-voor-stap 40000 bytes opschuiven :)
Die Bitmap constructor die met een resource handle werkt al geprobeerd? Gezien je codesnippet lijkt het erop of je dat niet doet, wellicht werkt die beter.
Edit4:
Het is inmiddels gelukt om een PNG plaatje te laden met alpha data en op een image te blenden.
Ik vraag me nog wel af waarom het volgende niet werkt en hoe het wel moet:
code:
1
2
3
4
5
Byte[] data = (Byte[])(rm.GetObject("Alpha.raw"));
System.IntPtr k = new System.IntPtr(data[0]);
Bitmap si = new Bitmap(10, 10, 4, 
System.Drawing.Imaging.PixelFormat.Format32bppArgb,k);
pg2.DrawImage(si,0,0);

Er ontstaat dan ene NullPointerException bij het uitvoeren van de laatste regel.
si bevat wel data? En de grootte van je ingelezen data is wel gelijk aan de opgegeven groottes van de bitmap die je er van maakt?

[ Voor 4% gewijzigd door Verwijderd op 27-11-2002 15:14 . Reden: /me is niet altijd * nickname, domme parser. $*#&^@&$^@# ]


Verwijderd

Topicstarter
Verwijderd schreef op 27 November 2002 @ 15:13:
Ik hoop het voor je, maar zou er niet altijd op vertrouwen. Dit zal alleen goed werken onder XP, windows 98 / ME hebben vziw wel .NET ondersteuning maar geen alphablending in de GDI layer.
Inderdaad. Maar wat ik ga maken is alleen voor mij bedoeld, dus ik maak me niet druk om win98 support.
Die Bitmap constructor die met een resource handle werkt al geprobeerd? Gezien je codesnippet lijkt het erop of je dat niet doet, wellicht werkt die beter.
Ja, uit een resource gaat wat sneller. Dan gebruik ik:
code:
1
Bitmap si = (Bitmap)rm.GetObject("Island");

"Island" staat dan voor een resource Island.png (32-bit) en transparantie laden werkt prima! (dus zowel uit resource als uit disk bestand, geen gedoe met TGA of pixel formats)
si bevat wel data? En de grootte van je ingelezen data is wel gelijk aan de opgegeven groottes van de bitmap die je er van maakt?
Ik heb het gecontroleerd, inderdaad zat daar ergens de fout. Ik had de Stride parameter niet goed gezet (moest width * 4 zijn). Met width=100, height=100 en stride=400
edit: Het werkt toch nog niet...

[ Voor 3% gewijzigd door Verwijderd op 27-11-2002 16:10 ]


  • alley
  • Registratie: Mei 2002
  • Laatst online: 18-08 20:40

alley

ahuh

TlighT schreef op 27 november 2002 @ 10:28:
[...]

Hoe dat in GDI+ moet staat in dat linkje wat je gisteren gepost hebt:


[...]
Precies, dus de topic kan wel gesloten worden.... gaat nergens meer over :9

I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)


Verwijderd

Topicstarter
Gaat wel ergens over... offtopic dingen :) Ik probeer nu een RAW bestand in een bitmap te gooien. Nu doe ik het zo:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Byte[] data = (Byte[])(rm.GetObject("Island.raw"));
Bitmap si2 = new Bitmap(200,200,PixelFormat.Format32bppArgb);
BitmapData bd = si2.LockBits(new Rectangle(0,0,200,200),ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
unsafe{
byte * p = (byte *)bd.Scan0;
for (int i=0;i<200*200*4;i++) 
p[i] = data[i];
}
si2.UnlockBits(bd);
float[][] f = {new float[]{0,0,1,0,0},new float[]{0,1,0,0,0},
new float[]{1,0,0,0,0},new float[]{0,0,0,1,0},new float[]{0,0,0,0,1}};
ColorMatrix cm = new ColorMatrix(f);
ImageAttributes attr = new ImageAttributes();
attr.SetColorMatrix(cm);
pg2.DrawImage(si2,new Rectangle(0,0,pictureBox1.Image.Width,pictureBox1.Image.Height),
0,0,200,200,GraphicsUnit.Pixel,attr);

Zoals je ziet worden de bytes in een array (byte[]) opgeslagen en een voor een naar de bitmapdata gekopieerd. Maar kun je ook de data uit de resource meteen in de bitmap data laden? (volgens mij wel maar ik ben nog niet zo bekend met c#)

[ Voor 6% gewijzigd door Verwijderd op 27-11-2002 17:12 ]


Verwijderd

Bitmap bmFoo = new Bitmap(rm, "Island");

werkt dat niet?
Pagina: 1