how to crop an image
BlitzMax Forums/BlitzMax Beginners Area/how to crop an image
| ||
| Hi ! i need some help to have idea how to crop a png image. Imagine that i've a classic 2d sprite on the image at the center. I need to crop the image to delete the transparent pixels arround the sprite ! (into a pixmap) In fact i've coded a program to automatically make an anim strip from image files. Now i need to center automatically the sprite on each imagestrip frame (before). Thanks to post algo or sample. (Here my code, sorry i use french into it)
' Assemble des images pour faire une imagestrip
Strict
Global seed
SeedRnd MilliSecs()
seed=RndSeed()
Global Largeur
Global Hauteur
Global Dossier:String
Global DebutNomFichier:String
Global NomFichierSortie:String = "image_strip_finale_" + Rand (0, 5000) + ".png"
Notify "Le programme débute..."
Dossier:String = RequestDir:String("Veuillez indiquer le dossier ou se trouve les images")
If Dossier:String = "" Then
Notify "Ne trouve pas le dossier, traitement annulé"
End
End If
DebutNomFichier = RequestFile("Sélectionnez le premier fichier à traiter", "Image Files:png;")
If DebutNomFichier = "" Then
Notify "Fichier non renseigné, traitement annulé"
End
Else
DebutNomFichier = Left (DebutNomFichier, Len (DebutNomFichier) - 7)
Notify "base fichier = '" + DebutNomFichier + "'"
End If
Global Nombre_fichiers = 16
Global hImage:TImage[Nombre_fichiers+1]
' préchargement des fichiers
For Local i = 1 To Nombre_fichiers
Local Nomfic:String
If i <= 9 Then
Nomfic = DebutNomFichier$ + "00" + String(i) + ".png"
Else
Nomfic = DebutNomFichier$ + "0" + String(i) + ".png"
End If
hImage[i] = LoadImage (NomFic:String, DYNAMICIMAGE)
Largeur = ImageWidth (hImage[i])
Hauteur = ImageHeight (hImage[i])
If hImage[i] = Null Then
Notify "Erreur ne trouve pas le fichier '" + Nomfic:String + "' !"
End
End If
Next
Local ImageSortie:TPixmap = CreatePixmap (Largeur * Nombre_fichiers, Hauteur, PF_BGRA8888)
Local decalx = 0
Local a
Local pixmap:TPixmap
Notify "Traitement commence avec largeur = " + Largeur + ", hauteur = " + Hauteur + "."
ImageSortie.ClearPixels(0)
For Local i = 1 To Nombre_fichiers
pixmap = LockImage:TPixmap(hImage[i], 0, True, True)
For Local y = 0 To Hauteur - 1
For Local x = 0 To Largeur - 1
a = ReadPixel (pixmap, x, y)
WritePixel (ImageSortie, x + decalx, y, a)
Next
Next
UnlockImage(hImage[i], 0)
decalx = decalx + Largeur
Next
SavePixmapPNG(ImageSortie, Dossier:String + "/" + NomFichierSortie:String)
Notify "Traitement terminé, fichier : " + Dossier:String + "/" + NomFichierSortie:String + " écrit."
Last edited 2010 |
| ||
| Sorry Hub, I am not sure I understand exactly what you are trying to do. Are you trying to figure out how to put images in the center of a frame or are you trying to remove the the transparent color from an image while incorporating it to the frames image? Or both? Do all of the images have alpha for transparency? Are all of your images PF_BGRA8888 format? finally are you trying to cut out an image from another image to paste into the frames image? |
| ||
Thanks for your help Jesse. Finally i've written this code and it works well !
' Assemble des images pour faire une imagestrip
Strict
Global seed
SeedRnd MilliSecs()
seed=RndSeed()
Global Largeur
Global Hauteur
Global Dossier:String
Global DebutNomFichier:String
Global NomFichierSortie:String = "image_strip_finale_" + Rand (0, 5000) + ".png"
Notify "Le programme débute..."
Dossier:String = RequestDir:String("Veuillez indiquer le dossier ou se trouve les images")
If Dossier:String = "" Then
Notify "Ne trouve pas le dossier, traitement annulé"
End
End If
DebutNomFichier = RequestFile("Sélectionnez le premier fichier à traiter", "Image Files:png;")
If DebutNomFichier = "" Then
Notify "Fichier non renseigné, traitement annulé"
End
Else
DebutNomFichier = Left (DebutNomFichier, Len (DebutNomFichier) - 7)
Notify "base fichier = '" + DebutNomFichier + "'"
End If
Global Nombre_fichiers = 16
Global hImage:TImage[Nombre_fichiers+1]
' préchargement des fichiers
For Local i = 1 To Nombre_fichiers
Local Nomfic:String
If i <= 9 Then
Nomfic = DebutNomFichier$ + "00" + String(i) + ".png"
Else
Nomfic = DebutNomFichier$ + "0" + String(i) + ".png"
End If
hImage[i] = LoadImage (NomFic:String, DYNAMICIMAGE)
Largeur = ImageWidth (hImage[i])
Hauteur = ImageHeight (hImage[i])
If hImage[i] = Null Then
Notify "Erreur ne trouve pas le fichier '" + Nomfic:String + "' !"
End
End If
Next
Local ImageSortie:TPixmap = CreatePixmap (Largeur * Nombre_fichiers, Hauteur, PF_BGRA8888)
Local decalx = 0
Local a
Local pixmap:TPixmap
Notify "Traitement commence avec largeur = " + Largeur + ", hauteur = " + Hauteur + "."
ImageSortie.ClearPixels(0)
' algo crop
For Local i = 1 To Nombre_fichiers
Local nx1 : Int
Local ny1 : Int
Local nx2 : Int
Local ny2 : Int
pixmap = LockImage:TPixmap(hImage[i], 0, True, True)
' crop haut
Local Compteur
ny1 = 0
For Local y=0 To Hauteur - 1
compteur = 0
For Local x=0 To Largeur - 1
a = ReadPixel (pixmap, x, y)
If a = 0 Then
Compteur = Compteur + 1
End If
Next
If Compteur = Largeur Then
ny1 = ny1 + 1
Else
Exit
End If
Next
' crop bas
ny2 = Hauteur - 1
For Local y = Hauteur-1 To 0 Step - 1
compteur = 0
For Local x=0 To Largeur-1
a = ReadPixel (pixmap, x, y)
If a = 0 Then
Compteur = Compteur + 1
End If
Next
If Compteur = Largeur Then
ny2 = ny2 - 1
Else
Exit
End If
Next
' crop gauche
nx1 = 0
For Local x=0 To Largeur - 1
compteur = 0
For Local y=0 To Hauteur - 1
a = ReadPixel (pixmap, x, y)
If a = 0 Then
Compteur = Compteur + 1
End If
Next
If Compteur = Hauteur Then
nx1 = nx1 + 1
Else
Exit
End If
Next
' crop droite
nx2 = Largeur - 1
For Local x = Largeur-1 To 0 Step - 1
compteur = 0
For Local y=0 To Hauteur - 1
a = ReadPixel (pixmap, x, y)
If a = 0 Then
Compteur = Compteur + 1
End If
Next
If Compteur = Hauteur Then
nx2 = nx2 - 1
Else
Exit
End If
Next
Print "Crop : x1=" + nx1 + ",y1=" + ny1 + ",x2=" + nx2 + ",y2=" + ny2
' calcule l'écart
Local posx = (Largeur - (nx2-nx1)) / 2
Local posy = (Hauteur - (ny2-ny1)) / 2
Print "PosX=" + posX + ",PosY=" + PosY
pixmap = LockImage:TPixmap(hImage[i], 0, True, True)
Local incx
Local incy
incx = PosX + decalX
incy = PosY
For Local y = ny1 To ny2
incx = PosX + decalX
For Local x = nx1 To nx2
a = ReadPixel (pixmap, x, y)
'Print "incx=" + incx + ",incy=" + incy
WritePixel (ImageSortie, incx, incy, a)
incx = incx + 1
Next
incy = incy + 1
Next
UnlockImage(hImage[i], 0)
decalx = decalx + Largeur
Rem
pixmap = LockImage:TPixmap(hImage[i], 0, True, True)
For Local y = 0 To Hauteur - 1
For Local x = 0 To Largeur - 1
a = ReadPixel (pixmap, x, y)
WritePixel (ImageSortie, x + decalx, y, a)
Next
Next
UnlockImage(hImage[i], 0)
decalx = decalx + Largeur
End Rem
Next
SavePixmapPNG(ImageSortie, Dossier:String + "/" + NomFichierSortie:String)
Notify "Traitement terminé, fichier : " + Dossier:String + "/" + NomFichierSortie:String + " écrit."
|
| ||
| Are you not aware of PixmapWindow()? |
| ||
| Thanks Gfk. In fact this code detect the transparent pixels arround the sprite. As the sprite could be not centered inside the first image, i center it into the new imagestrip frame. It's not optimized code, but works for my needs. i use lightwave to produce 3d to 2d sprite. i animate them into lightwave. When i render the animation, ligthwave produce many png files (each file is for an animation frame). It's difficult for me to center the sprite inside lightwave. Before this code i've used photoshop and copy paste ! |