Weiße Bildränder wegschneiden

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Weiße Bildränder wegschneiden

Beitrag 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
Hygge
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Beitrag 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
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Beitrag von Kukulkan »

Hi Kiffi,

Ich tippe mal auf 2 bis 3...

Volker
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag 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
Hygge
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Beitrag 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
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Beitrag 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.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag 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
Hygge
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kiffi
Beiträge: 10621
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag 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
Hygge
Benutzeravatar
DrShrek
Beiträge: 1970
Registriert: 08.09.2004 00:59

Beitrag 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?
Siehste! Geht doch....?!
PB*, *4PB, PetriDish, Movie2Image, PictureManager, TrainYourBrain, ...
Antworten