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.
Welke taal? De meeste talen bevatten wel zoiets. Heet doorgaans fill of zo.
edit:
Sorry. titel niet gelezen
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.
ms-help://MS.VSCC/MS.MSDNVS/cpref/html/frlrfSystemDrawingGraphicsClassFillRectangleTopic.htm
gevonden in 7 seconden.
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?
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?
Gebruik Graphics.FillPath of Graphics.FillRegion om een willekeurig gebied te vullen.
[ Voor 7% gewijzigd door TlighT op 26-11-2002 15:44 ]
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
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?
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?
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).
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
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.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...
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.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?
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.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).
GDI (zonder de plus) heeft wel een floodfill hoor, die doet precies wat WhizzVin wil.. dus het bestaat zekerVerwijderd 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.
[ 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)
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.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?
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.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.
Als er meerdere losse gebieden ontstaan met dezelfde kleur, dan wordt het gebied genomen waar de gekozen pixel in ligt.
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.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.
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.
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....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.
Maar goed, we raken offtopic
I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)
Hoe dat in GDI+ moet staat in dat linkje wat je gisteren gepost hebt:alley schreef op 27 november 2002 @ 10:17:
[...]
Maar goed, we raken offtopicwant de vraag is hoe het in GDI+ moet
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
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.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....
[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 ]
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.
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.
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.
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: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)
Terwijl Whizzvin in z'n openingspost zegt:Als het niet realtime moet, zou ik fijn zelf in een 3 regelige forloop de pixels afsjouwen. Waarschijnlijk was je al klaargeweest.
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.Natuurlijk kan ik wel zelf een functie maken die alle aangesloten pixels scant, maar dat lijkt me niet de snelste oplossing.
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.
Verwijderd
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.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:
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.
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)[...]
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.
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).
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.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.
Verwijderd
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.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.
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.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).
Wat voor bitmap laadt je? Een TGA? Of een bitmap zonder alphachannel zoals BMP of JPG.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.
HOE teken je? MIddels blending? Of kletter je de bitmap zo op het scherm?code:
1Bitmap 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.
LoadImage?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.
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.
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.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.
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:
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.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.
Ik probeerde eerst BMP (met alphachannel, dus RGBA formaat), maar de alpha laadt-ie dus niet.Wat voor bitmap laadt je? Een TGA? Of een bitmap zonder alphachannel zoals BMP of JPG.
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().
Blending wordt al automatisch gedaan door C#.NET. Werkt goedHOE teken je? MIddels blending? Of kletter je de bitmap zo op het scherm?
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.Zie voor transparent drawing de MakeTransparent method, maar dat had je UITERAARD allang bekeken.
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 opschuivenVia .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.
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
Die 'A' in BMP is een wassenneus. BMP kun je nl. nooit opslaan in 32 bpp, maar altijd in 24bpp of kleiner.Verwijderd schreef op 27 November 2002 @ 13:35:
[...]
Ik probeerde eerst BMP (met alphachannel, dus RGBA formaat), maar de alpha laadt-ie dus niet.
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 zijnEdit1:
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 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 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.
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, 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
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?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 5Byte[] 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 4% gewijzigd door Verwijderd op 27-11-2002 15:14 . Reden: /me is niet altijd * nickname, domme parser. $*#&^@&$^@# ]
Inderdaad. Maar wat ik ga maken is alleen voor mij bedoeld, dus ik maak me niet druk om win98 support.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.
Ja, uit een resource gaat wat sneller. Dan gebruik ik: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.
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)
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=400si 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?
edit: Het werkt toch nog niet...
[ Voor 3% gewijzigd door Verwijderd op 27-11-2002 16:10 ]
Precies, dus de topic kan wel gesloten worden.... gaat nergens meer overTlighT schreef op 27 november 2002 @ 10:28:
[...]
Hoe dat in GDI+ moet staat in dat linkje wat je gisteren gepost hebt:
[...]
I am always doing that which I can not do, in order that I may learn how to do it. (Pablo Picasso)
Gaat wel ergens over... offtopic dingen
Ik probeer nu een RAW bestand in een bitmap te gooien. Nu doe ik het zo:
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#)
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 ]
Pagina: 1