ResampleImage
Übersicht

![]() |
LunatixBetreff: ResampleImage |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hi.
Ich habe angefangen, eine Funktion zu machen, die ein Bild vergrössern/kleinern kann. Zum einarbeiten wollte ich erstmal "Pixel Resize" machen, welches, wie ich dachte, nicht so schwer ist. Ists auch nicht, solange das bild die hälte des originales gross ist. (Zum vergrössern wollte ich später kommen, wenn ich verkleinern kann, also nicht so wichtig) Problem dabei : da 512 die hälfte von 1024 ist, muss ich hier nur alle 2 pixel 2pixel auslassen. Bloß - wie lasse ich nun bei anderen grössen 1.4 pixel aus... ? Mein Ansatz : Code: [AUSKLAPPEN] Framework brl.max2d
Import brl.glmax2d Import brl.pngloader Import brl.jpgloader Import brl.retro Import brl.basic Graphics 1024,768,0 SetClsColor 255,255,255 Local image:TImage = LoadImage("grassland.png") Rem Hier beliebiges bild einsetzen, ich hatte hier 1024x768 sowie > 2500x1900 (foto) End Rem DrawImage image,0,0 Flip Cls WaitKey Print "resampling" image = ResampleImage(image,image.width/2,image.height/2,0) Print "ready" Repeat DrawImage image,0,0 Flip Cls Until KeyHit(KEY_ESCAPE) End Function ResampleImage:TImage(image:TImage,width:Float,height:Float,sampling:Int=0) If image.width = width And image.height = height Return image Local nImage:TImage = TImage.Create(width,height,1,MASKEDIMAGE|DYNAMICIMAGE,255,0,0) nImage.seqs[0]=0 nImage.Frames[0]=Null nImage.Pixmaps[0] = CreatePixmap(width,height,PF_RGBA8888) 'Hier ist dazu zu sagen, dies ist wie LockImage, nur mit eigener Pixmap Select sampling Case 0 Local xFactor:Float = Float(image.width)/Float((image.width-width)) Local yFactor:Float = Float(Image.height)/Float((Image.height-height)) If xFactor-Int(xFactor) > 0.5 xFactor = Ceil(xFactor) Else xFactor = Floor(xFactor) EndIf If yFactor-Int(yFactor) > 0.5 yFactor = Ceil(yFactor) Else yFactor = Floor(yFactor) EndIf For Local x:Float = 0 To Image.width-1 'Print x If xpos<=xFactor Or x=0 For Local y:Float = 0 To Image.height-1 If ypos<=yFactor Or y=0 If nx < nImage.width And ny < nImage.height nImage.pixmaps[0].WritePixel nx,ny,image.pixmaps[0].ReadPixel(x,y) EndIf ny:+1 ypos:+1 Else ypos=0 EndIf Next ny=0 nx:+1 Else xpos=0 EndIf xpos:+1 Next Return nImage End Select End Function Ich hoffe, er ist wenigstens zum Teil richtig... ![]() Ceil und Floor müssen allerdings wahrscheinlich raus, bloß bin ich dann immernoch bei 1.4 oder anderen Pixeln... steh grad so ein bisschen auf dem Schlauch ... ![]() |
||
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen... |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Garnicht
Solange du da nicht mit Filtern und damit im Klartext mit Matrizen arbeitest, wirst du nirgends hin kommen. "Auslassen" ist keine Lösung, das ist ein Hack der in speziellen Fällen funktioniert. Aber was wenn 800x600 auf 320x290 resampled werden sollen? |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Lunatix |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mh ok, dann hab ich wohl komplett falch angefangen. Werd ich mir das mit den Matrizen mal anschauen... naja man kann ja nicht alles wissen ![]() Edit: Naja, also nun weiss ich (hoffe ich doch) das eine Matrix Pitch,Yaw,Roll und die Skalierung speichert. Nur irgendwie beginnt meine Suche wohl ziehmlich im Nirgendwo, ich find einfach keinen Ansatz... könntest du mir eventuell einen geben oder so etwas in der Art ? |
||
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen... |
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: "Auslassen" ist keine Lösung, das ist ein Hack der in speziellen Fällen funktioniert.
ist kein Hack - diese Methode nennt sich "nearest neighbor" - und ist Qualitativ eher die schlechteste Wahl... der 2. einfachste und 2. schnellste Algorithmus ist "bilineares filtering" - lässt sich auch ohne matrizen errechnen der beste ist glaube ich lanczos - zur vereinfachung/beschleunigung wird hier mit matrizen gerechnet... |
||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Inwiefern ist Billinear etwas anders als eine Matrixoperation?
Alles was Pixel um sich herum miteinbezieht ist eine Matrixoperation ... |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Lunatix |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mh ok - Bilinear Filtering. So wie ich das nun gelesen habe, ist das so, das aus Vier Pixeln einer berechnet wird... wenn wir ein Quad. von 1-4 haben, würden 1 & 2 verrechnet und der Wert dann mit den unteren - genau hab ichs noch nciht verstanden aber naja. Bloss - wenn ich jetz nur 100 Pixel vom gesamtbild wegnehmen muss, wie entscheide ich dann, welche Pixel a) wegmüssen und b) geglättet werden müssen? | ||
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen... |
![]() |
maximilian |
![]() Antworten mit Zitat ![]() |
---|---|---|
/edit: Habs noch mal ein bisschen optimiert.
Code: [AUSKLAPPEN] Graphics 640, 480, 16, 2
SetBuffer BackBuffer() Local scale# = 1 Local img = LoadImage("texture.bmp") IMAGE_WIDTH = ImageWidth(img)-1 IMAGE_HEIGHT = ImageHeight(img)-1 bnk_img = CreateBank(ImageWidth(img)*ImageHeight(img)*4) bnk_pitch = ImageWidth(img) For y = 0 To IMAGE_HEIGHT For x = 0 To IMAGE_WIDTH PokeInt(bnk_img, (y*ImageWidth(img)+x)*4, ReadPixel(x, y, ImageBuffer(img))) Next Next While Not KeyHit(1) LockBuffer BackBuffer() dx# = 1/scale# dy# = 1/scale# w = Floor(IMAGE_WIDTH*scale#-1) h = Floor(IMAGE_HEIGHT*scale#-1) py# = 0 For y = 0 To h px# = 0 y1 = Floor(py) fractY# = py# - y1 y2 = (y1 + 1) And IMAGE_HEIGHT For x = 0 To w x1 = Floor(px) fractX# = px# - x1 x2 = (x1 + 1) And IMAGE_WIDTH col = PeekInt(bnk_img, (x1+y1*bnk_pitch) Shl 2) Weight# = (1 - fractX#)*(1 - fractY#) ar = (col Shr 16) And $FF: ag = (col Shr 8) And $FF: ab = (col) And $FF r = ar*Weight#: g = ag*Weight#: b = ab*Weight# col = PeekInt(bnk_img, (x1+y2*bnk_pitch) Shl 2) Weight# = (1 - fractX#)*fractY# ar = (col Shr 16) And $FF: ag = (col Shr 8) And $FF: ab = (col) And $FF r = r + ar*Weight#: g = g + ag*Weight#: b = b + ab*Weight# col = PeekInt(bnk_img, (x2+y1*bnk_pitch) Shl 2) Weight# = fractX#*(1 - fractY#) ar = (col Shr 16) And $FF: ag = (col Shr 8) And $FF: ab = (col) And $FF r = r + ar*Weight#: g = g + ag*Weight#: b = b + ab*Weight# col = PeekInt(bnk_img, (x2+y2*bnk_pitch) Shl 2) Weight# = fractX#*fractY# ar = (col Shr 16) And $FF: ag = (col Shr 8) And $FF: ab = (col) And $FF r = r + ar*Weight#: g = g + ag*Weight#: b = b + ab*Weight# WritePixelFast x, y, (r Shl 16) + (g Shl 8) + b px# = px# + dx# Next py# = py# + dy# Next UnlockBuffer BackBuffer() If KeyDown(201) Then scale# = scale# + 0.05 If KeyDown(209) Then scale# = scale# - 0.05 Flip Cls Wend End Bild-Auf, Bild-Ab zum zoomen. Lässt sich sicherlich noch gut optimieren (evtl. Fixed point, k.A. obs auf heutigen Prozis noch was bringt), und wird mit BMax sowieso schneller laufen. PS: Hab auch noch ne Fassung für ARM Asm/NDS als fertige universelle Funktion. ![]() |
||
Variety is the spice of life. One day ignore people, next day annoy them. |
- Zuletzt bearbeitet von maximilian am Do, Apr 19, 2007 14:00, insgesamt einmal bearbeitet
![]() |
TheShadowModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Inwiefern ist Billinear etwas anders als eine Matrixoperation?
Alles was Pixel um sich herum miteinbezieht ist eine Matrixoperation ... eigentlich nicht - ich meine Matrizen aus mathematischer Sicht... @LordChaos hat du dir das selbst zusammengestrickt? weil ich meine bilinear hatte etwas andere formeln... |
||
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2 |
![]() |
maximilian |
![]() Antworten mit Zitat ![]() |
---|---|---|
Kommt daher: http://www.gamedev.net/referen...cle810.asp
Also das Resultat sieht zumindest verdammt bilinear aus. ![]() |
||
Variety is the spice of life. One day ignore people, next day annoy them. |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group