Seite 1 von 3

Weiße Bildränder wegschneiden

Verfasst: 27.11.2006 17:42
von Kiffi
Hallo,

ich bekomme des öfteren Bilder, die einen breiten weißen Rand haben.
Diesen schneide ich bisher mit IrfanView weg (nicht-weißen Bereich
markieren, Ctrl + X, Ctrl + V). Das pixelgenaue Markieren ist jedoch gerade
bei großen Bildern ein wenig fummelig. Schön wäre es, wenn man ein Tool
hätte, dass das automatisch machen kann. Im Netz gibt es auch das ein oder
andere Programm dafür, aber das sind so megabyteschwere
eierlegende-Wollmilchsäue (GIMP & Co), die ich für oversized halte.

Als Grafix-Noob weiß ich jetzt nicht, wie leicht / wie schwierig es ist, so ein
Tool zu schreiben.

Meine Frage an die Pixeljongleure: Wenn Ihr das Tool auf einer
Skala von 1 (leicht / in 30 Minuten zusammengehackt)
bis 10 (schwierig/langwierig) einordnen müsstet, welche Note würdet ihr
vergeben?

Danke im voraus & Grüße ... Kiffi

Verfasst: 27.11.2006 17:47
von #NULL
wo ist der rand?
drum herum? nur rechts? ..?


..eine langsame variante ist vermutlich nicht sehr schwer (jedenfals jucken mir schon die finger :mrgreen: )
1-3

Verfasst: 27.11.2006 18:02
von Kukulkan
Hi Kiffi,

Ich tippe mal auf 2 bis 3...

Volker

Verfasst: 27.11.2006 18:06
von Kiffi
> wo ist der rand?

überall. ;-)

Ich bekomme ein Bild mit beispielsweise einem Logo. Das Logo ist in die Mitte
des Bild gepappt. Drumherum weißer Rand.

Grüße ... Kiffi

Verfasst: 27.11.2006 18:24
von #NULL
so geht's schonmal, aber ich kann es noch sicherer und komfortabler machen, wenn du willst.

bmp, jpg, png

drag'n'drop/paramter oder einfach starten und mit den requester bedienen.

nur wenn kein rand da is, weiß ich nich was passiert..(aber ich guck's mir noch an)

Code: Alles auswählen

invalidColor=$ffffff

UseJPEGImageDecoder()
UsePNGImageDecoder()

file.s=ProgramParameter()
If Not file
  file=OpenFileRequester("choooose", "", "*.bmp;*.jpg;*.png|*.bmp;*.jpg;*.png", 0)
EndIf

If Not file
  End
EndIf


If Not LoadImage(0,file)
  MessageRequester("error", "can't load image!" )
  End
EndIf

w=ImageWidth(0)-1
h=ImageHeight(0)-1


StartDrawing( ImageOutput(0) )

  For i=0 To w
    For k=0 To h
      If Not Point(i,k)=invalidColor
        start_i=i
        Break 2
      EndIf
    Next
  Next

  For k=0 To h
    For i=0 To w
      If Not Point(i,k)=invalidColor
        start_k=k
        Break 2
      EndIf
    Next
  Next
  
  For i=w To 0 Step -1
    For k=h To 0 Step -1
      If Not Point(i,k)=invalidColor
        stop_i=i
        Break 2
      EndIf
    Next
  Next

  For k=h To 0 Step -1
    For i=w To 0 Step -1
      If Not Point(i,k)=invalidColor
        stop_k=k
        Break 2
      EndIf
    Next
  Next

StopDrawing()


If Not CreateImage(1, stop_i-start_i+1, stop_k-start_k+1)
  MessageRequester("error", "can't create image!" )
  End
EndIf


StartDrawing( ImageOutput(1) )
  DrawImage(ImageID(0), -start_i, -start_k )
StopDrawing()

Select LCase( GetExtensionPart(file) )
  Case "bmp"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_BMP )
  Case "jpg"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_JPEG, 10)
  Case "png"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_PNG )
EndSelect

Verfasst: 27.11.2006 19:35
von #NULL
also mit bmp (und png) klappt alles. funzt aber nur mit exakt weißem rand. die randfrabe kann in der ersten codezeile geändert werden. bei schlumpi-farben, wie z.b. im jpg-format, geht's nich. weiß aber nicht ob das am quellbild, oder nur an dem encoder von PB liegt.
hier gleich mit test-bmp's:
http://www.wannabephoenix.de/PB/killBorder.zip

..achso, das result wird immer im selben ordner wie das quellbild gespeichert, mit einer tilde (~) vorn am namen.

Verfasst: 28.11.2006 00:08
von Kiffi
> so geht's schonmal,

ehj, das ist gemein! Ich wollte das doch schreiben! ;-)

Vielen lieben Dank für den Code! :allright: Funktioniert mit den im Zip
liegenden BMPs wunderbar. Allerdings ist mir das -- selbst im Debugger -- im
Büro mit einem JPG sang- und klanglos abgesemmelt (der Rand besteht IMO
aus reinem Weiß; also keine Schlumpi-Farben). Ich werde das morgen noch
mal genauer testen.

Nochmals Danke & Grüße ... Kiffi

// Edit: Zum Abschluss des Tages hier noch mal ein Versuch, Deinen Code
ein wenig schneller zu machen. Ergebnis: 'n Schlückchen schneller, aber
dafür auch unübersichtlicher. :|

Der Grundgedanke war eigentlich, dass die x- und y-Koordination in
Schleife 2, 3 und 4 nicht zu den vollen Ausmaßen des Bildes ausgefahren
werden müssen, sondern lediglich bis zu den bis dahin ermittelten
Grenzen.

Ich geh jetzt in die Heia!

Code: Alles auswählen

invalidColor=$FFFFFF
UseJPEGImageDecoder()
UsePNGImageDecoder()
UseJPEGImageEncoder()
UsePNGImageEncoder()

file.s=ProgramParameter()
If Not file
  file=OpenFileRequester("choooose", "", "*.bmp;*.jpg;*.png|*.bmp;*.jpg;*.png", 0)
EndIf

If Not file
  End
EndIf

If Not LoadImage(0,file)
  MessageRequester("error", "can't load image!" )
  End
EndIf

w=ImageWidth(0)-1
h=ImageHeight(0)-1

If Not w*h
  MessageRequester("error", "invalid 	proportions."+#CRLF$+"width or height is 0!" )
  End
EndIf

z1=ElapsedMilliseconds()

StartDrawing( ImageOutput(0) )

x=0:y=0
Repeat
  Repeat
    If Point(x,y)<>invalidColor
      x1=x ; linker rand
      Break 2
    EndIf
    If y=h:Break:EndIf
    y+1
  ForEver
  y=0
  If x=w:Break:EndIf
  x+1
ForEver

x=x1:y=0
Repeat
  Repeat
    If Point(x,y)<>invalidColor
      y1=y ; oberer rand
      Break 2
    EndIf
    If x=w:Break:EndIf
    x+1
  ForEver
  x=x1
  If y=h:Break:EndIf
  y+1
ForEver 

x=x1:y=h
Repeat
  Repeat
    If Point(x,y)<>invalidColor
      y2=y ; unterer rand
      Break 2
    EndIf
    If x=w:Break:EndIf
    x+1
  ForEver
  x=x1
  If y=0:Break:EndIf
  y-1
ForEver 

x=w:y=y1
Repeat
  Repeat
    If Point(x,y)<>invalidColor
      x2=x ; rechter rand
      Break 2
    EndIf
    If y=y2:Break:EndIf
    y+1
  ForEver
  y=y1
  If x=0:Break:EndIf
  x-1
ForEver 

StopDrawing()

z2 = ElapsedMilliseconds()

MessageRequester("", Str( z2-z1))

cw=x2-x1+1
ch=y2-y1+1

If Not (cw>0 And ch>0)
  MessageRequester("error", "kidding?!? that's a blank picture!" )
  End  
EndIf

If Not CreateImage(1, cw,ch)
  MessageRequester("error", "can't create image!" )
  End
EndIf

StartDrawing( ImageOutput(1) )
DrawImage(ImageID(0), -x1, -y1 )
StopDrawing()

Select LCase( GetExtensionPart(file) )
  Case "bmp"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_BMP )
  Case "jpg"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_JPEG, 10)
  Case "png"
    SaveImage(1, GetPathPart(file)+"~"+GetFilePart(file), #PB_ImagePlugin_PNG )
EndSelect

Verfasst: 28.11.2006 06:03
von Kaeru Gaman
du könntest das ganze noch etwas beschleunigen:

du gehst zuerst nur auf einer höhe mittig immer weiter nach innen,
bis du auf ein nicht-weißes pixel triffst.
in dieser spalte-1 beginnend testest du nun jede spalte von innen nach außen,
(von der mittelachse nach oben und unten) ob du auf ein nicht-weißes pixel triffst.
wenn ja, gehst du wieder eine spalte weiter nach außen,
wenn nein, hast du deine freie spalte gefunden.

das funktioniert natürlich nur für zusammenhängende bildinformationen.
wenn die eigentliche bildinformation auch "inseln" bilden kann,
ist das verfahren unbrauchbar.

Verfasst: 28.11.2006 12:37
von Kiffi
Kaeru Gaman hat geschrieben:du könntest das ganze noch etwas beschleunigen:
gute Idee! Aber leider...
Kaeru Gaman hat geschrieben:das funktioniert natürlich nur für zusammenhängende bildinformationen.
wenn die eigentliche bildinformation auch "inseln" bilden kann,
ist das verfahren unbrauchbar.
Joh, das trifft auf meine Bilder zu.

Danke & Grüße ... Kiffi

Verfasst: 28.11.2006 13:33
von DrShrek
Was haltet Ihr von einen kleinen Alghorithmus Contest?

Aufgabe:
Wer schreibt den schnellsten Alghorithmus?

Es werden definierte Bilder getestet, bewertet die Geschwindigkeit bei jeden Bild + die Summe.

Es wird ein Programmgerüst geliefert mit einer leeren Funktion:
Rect = GetRect(Image, Color)

Einschränkungen:
1) Es darf nur die Point() Funktion zum Auslesen der Farbe verwendet werden.
2) Nur PB Code ohne Assembler und ohne externe DLL

Die Bilder sind:
1) Bild <> Color
2) Bild = Color
3) Bild mit nur 1 Insel
4) Bild mit n Inseln
5) Bild das wie ein X aussieht.
6) Bild das wie ein + aussieht.
7) Bild das nur 1 Pixel <> Color hat

Interesse?