2010-07-16 12 views
4

CE QUE JE SUIS en train de faireTImage Transparents sur les ordinateurs portables à Delphi 7

Je suis en train de dessiner plusieurs graphiques à un TImage, ces graphiques que je Draw se composent de couches ordonnées avec Foodfills et lignes. J'utilise plusieurs tampons pour assurer l'ordre et la double mise en mémoire tampon.

ce que je fais

procedure DrawScene(); 
var 
    ObjLength,LineLength,Filllength,Obj,lin,angle,i:integer; 
    Npoints : array[0..1] of Tpoint; 
    Objmap:TBitmap; 
    wholemap:TBitmap; 

begin 
    wholemap := TBitmap.Create; 
    wholemap.Width:=area; 
    wholemap.height:=area; 

    ObjLength:=length(Objects); 
    for Obj:=0 to (ObjLength-1) do 
    if objects[Obj].Visible then 
    begin 
    // create object bitmap 

    if Objects[obj].Tag='FBOX' then 
     begin 

     Objmap := TBitmap.Create; 
     Objmap.Width:=area; 
     Objmap.height:=area; 
     Objmap.Transparent:=true; 

     Objmap.Canvas.Rectangle((objects[obj].Boundleft-4)+objects[obj].Position.x,area-((objects[obj].boundtop+4)+objects[obj].Position.y),(objects[obj].boundright+4)+objects[obj].Position.x,area-((objects[obj].boundbottom-4)+objects[obj].Position.y)); 
     end; 
    //draw object 
    LineLength:=length(objects[Obj].Lines)-1; 
    angle:=objects[Obj].Rotation; 
    for lin:=0 to (LineLength) do 
    begin 
     for i:=0 to 1 do 
     begin 
     Npoints[i] := PointAddition(RotatePoint(objects[obj].Lines[lin].Point[i],angle),objects[obj].Position,false); 
     end; 
     Objmap:=DrawLine(Npoints[0].x,Npoints[0].y,Npoints[1].x,Npoints[1].y,objects[obj].Lines[lin].Color,Objmap); 
    end; 


    Filllength:=length(objects[Obj].Fills)-1; 
    for i:=0 to Filllength do 
     begin 
     Npoints[0]:=PointAddition(RotatePoint(objects[Obj].Fills[i].Point,objects[Obj].Rotation),objects[Obj].Position,false); 
     Objmap:=fillpoint(Npoints[0].x, Npoints[0].y,objects[Obj].Fills[i].color,Objmap); 
     end; 

     //write object to step frame 
     wholemap.Canvas.Draw(0,0,Objmap); 
     Objmap.Free; 


    end; 
    // write step frame to Visible Canvas 
    mainwindow.bufferim.Canvas.Draw(0,0,wholemap); 
    mainwindow.RobotArea.Picture.Graphic:=mainwindow.bufferim.Picture.Graphic; 


    wholemap.Free; 

end; 

ce que j'attends

je voir chaque objet d'image en couches sur le dessus les uns des autres, chaque couche d'image étant l'image complète de cette couche . im mon exemple c'est un robot avec un drapeau derrière. le drapeau est dessiné en premier, puis le robot.

ce que je reçois (sur un PC)

sur un pc-je obtenir ce que je pense et tout semble correct.

ce que je reçois (sur un ordinateur portable)

Sur près de tous les ordinateurs portables et certains PC, je ne vois que le robot. J'ai mis dans quelques déclarations pour voir si elle dessine le drapeau et c'est le cas. le jeu peut même interagir avec le drapeau de la manière correcte. une enquête plus approfondie m'a montré qu'il était seulement montre la dernière image tirée de mon « drawscene », et lorsque les images ont été tirées directement aux wholecanvas everthing apeared (cela ne peut être fait pour chevauchement remplir des raisons couches)

QU'EST-CE QUE JE PENSE EST EVENEMENT

donc ce que je déduis est que la propriété Timage.transparent du TImage ne fonctionne pas ou est en cours de calcul différemment sur certaines machines ..

je l'ai fait un test pour prouver et fait une rouge toile. Puis à cette toile j'ai dessiné à 0,0 i Timage avec la propriété transparent = true avec juste un point au milieu de la toile rouge. le resuly était une toile blanche avec un point au milieu. Je suppose et les résultats indiquent que les machines avec des pilotes graphiques très basiques semblent traiter le blanc ou le transparent comme du blanc, alors que des machines plus puissantes semblent traiter le NULL ou le transparent comme transparent.

Cela semble être un peu un échec en raison du fait que la propriété Timage.Transparent était vraie.

EDIT: MISE À JOUR !!! Il semblerait que sur les cartes graphiques ATI si une couleur est "nulle" alors elle est interprétée dans le format de PF24bit et donc pas de canal alpha et pas de transparence.

sur les cartes Nvidia il prend comme PF32bit et traite null comme transparent.

la façon évidente de contourner cela serait de définir le bitmaptype à PF32bit, mais cela ne fonctionne toujours pas. J'ai alors supposé que peut-être cela ne suffisait pas et je devrais m'assurer que l'arrière-plan est réglé sur transparent au lieu d'être laissé comme nulle.mais il n'y a pas d'outils (que je peux voir) dans le Timage pour définir la couleur avec alpha. toutes les fonctions de dessin de toile nécessitent un Tcolor qui est RVB 24 bits et ony un TcolorRef avec RGBA 32 bit ferait .... y at-il un moyen de dessiner avec alpha 0?

QU'EST-CE QUE JE CROIS QUE JE SAVOIR

Comment forcer la propriété Transparent pour travailler sur toutes les machines ou un moyen de rendre les ordinateurs portables coller pas transparent blanc Ou un moyen d'atteindre le même résultat .

Quelqu'un a des solutions ou des idées?

+1

Que ce soit un ordinateur portable ou un PC ne devrait pas être pertinent en tant que tel, mais la résolution de l'écran et surtout la profondeur de couleur est probablement. Pouvez-vous vérifier ces choses, au moins sur deux machines, l'une sur laquelle il fonctionne et l'autre sur laquelle il ne fonctionne pas? –

+0

Un autre problème possible: l'écran de votre ordinateur portable peut être incapable d'afficher vos couleurs (exemple: très légères nuances de toutes les couleurs) et il semble que le truc "Transparence" ne fonctionne pas, alors qu'en fait il fonctionne, mais vous Je ne le vois pas. Cette même chose arrive avec la plupart des projecteurs. Comment tester: imprimer votre application sur le PC, enregistrer en bitmap, copier des bitmaps sur un ordinateur portable. Ou l'inverse, imprimez l'écran sur votre ordinateur portable et vérifiez le bitmap sur PC. –

Répondre

2

J'utilise une bibliothèque graphique (de AggPas) pour aider avec des graphismes de dessin et une des choses que j'ai remarqué est que j'ai toujours besoin d'une ligne Bitmap.PixelFormat = pf32bit pour l'obtenir pour dessiner transparancies.

Cela dit que j'utilise transformImage de la bibliothèque AggPas pour copier l'image avec un fond transparent à un autre et AggPas accepte uniquement pf24bits ou pf32bits que les formats de pixels (sinon il ne se fixe pas au bitmap)

2

J'ai déjà observé un comportement similaire sur différentes machines (il y a quelques années).

Ils ont été provoqués par différentes cartes vidéo et pilotes. Soit les NVideo ou les ATI obtenaient de mauvais résultats, mais j'ai oublié lesquels.

Il pourrait être reproduit sur les deux ordinateurs portables et les ordinateurs ordinaires. Alors, quelles sont les cartes vidéo et les pilotes que vous utilisez?

--jeroen

+0

Cela semble être le problème. Après enquête, certaines machines avec la même profondeur de couleur que les machines de travail ne fonctionnent pas, et les couleurs qu'il ne parvient pas à afficher comprennent le noir sur blanc. Mais quand j'ai regardé les pilotes vidéo, j'ai trouvé que toutes les machines qui fonctionnaient avaient des pilotes/cartes Nvidia et toutes les machines qui n'avaient pas ATI. Y at-il un moyen de faire des choses? – Arthur

+0

@Arthur: à l'époque, je n'ai pas trouvé de solution pour le faire fonctionner. Mais alors le client s'est éloigné des machines basées sur ATI, ainsi le problème s'est résolu. –

1

Je définirais explicitement le format bitmap à pf32bit pour chaque bitmap que vous créez pour éviter que le problème ne convertisse les couleurs de 32 à 16 bits (si la résolution vidéo native des bitmaps est créée), ce qui pourrait interférer avec le fonctionnement de la transparence. En outre, j'ai eu plus de chance en définissant la couleur de transparence dans le passé.

Une autre option - peut-être une meilleure à long terme, est de définir à la place le canal Alpha sur les images (par exemple, utiliser des fichiers PNG), et d'utiliser la fonction GDI AlphaBlend() pour dessiner les graphiques.

Questions connexes