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 ! |