Tillerhilfe mit Kreis drüberlegen, ein Plugin für GIMP

Themen zum Bogenbau
Antworten
Benutzeravatar
Uranus79
Hero Member
Hero Member
Beiträge: 920
Registriert: 08.04.2017, 09:39

Tillerhilfe mit Kreis drüberlegen, ein Plugin für GIMP

Beitrag von Uranus79 » 20.02.2018, 15:58

Hallo FC'ler,

bei der Beurteilung von Tilleraufnahmen legt man ja gerne mal Kreise über ein Bild. Um das zu vereinfachen, habe ich ein Plugin für GIMP geschrieben (freies Bildverarbeitungsprogramm), was sowohl unter Windows wie auch Linux funktioniert (mit Windows getestet). Vielleicht hilft das auch mal jemand anderem, deswegen möchte ich es gerne teilen. Wie funktioniert es?

1.)
Das angehängte Python-Skript in das Plugin-Verzeichnis von GIMP legen (bei Windows: C:\Benutzer\NAME\.gimp-2.8\plug-ins\ , bei Linux je nach GIMP Version, ich schaue später mal nach). Für Linux das Skript ausführbar machen. Dateiname gimp-plugin-drawcircle.py verwenden.

2.)
In GIMP ein Bild des Bogens einladen

3.)
Mit lila Farbe (Code #FF00FF) mindestens drei oder sechs Punkte auf dem Bogen markieren (jeweils nur ein Pixel, zB per Bleistift-Tool, Größe auf 1 stellen). Entsprechend werden einer oder zwei Kreise gemalt. Ich male die z.B. auf den Rücken.

4.)
Im Kontextmenü "Filter" und dann "drawcircle" auswählen. Erkannte Punkte werden von links nach rechts als Punkte im Dreieck erkannt und Umkreise berechnet. Diese werden in einem zusätzlichen Layer als rote(r) Kreis(e) gezeichnet. Beispielbild habe ich angehängt. Es ist ein KREISTILLER, also echte Kreise werden gemalt!

Leider kann ich das Skript (eine Textdatei mit Python-Code) nicht als Anhang hochladen.
Ich habe es daher als Code-Block hier eingefügt.
Wenn man den Text rauskopiert und in eine Textdatei einfügt und diese unter o.g. Namen in das Verzeichnis legt, müßte es funktionieren.

Hoffe, das hilft, viele Grüße, Uranus.


Code: Alles auswählen

#!/usr/bin/env python
# coding=utf8

# Draw circle around three points
# Copyright (C) 2018  Thorsten Jordan.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# It can be executed by selecting the menu option: 'Filters/drawcircle'
# or by writing the following lines in the Python console (that can be opened with the
# menu option 'Filters/Python-Fu/Console'):
# >>> image = gimp.image_list()[0]
# >>> layer = image.layers[0]
# >>> gimp.pdb.python_fu_drawcircle(image, layer)

from gimpfu import *
import math
import array

markercolor = (255, 0, 255)

def render_circle(newLayer, coordinates):
   x1 = float(coordinates[0][0])
   y1 = float(coordinates[0][1])
   x2 = float(coordinates[1][0])
   y2 = float(coordinates[1][1])
   x3 = float(coordinates[2][0])
   y3 = float(coordinates[2][1])
   d = 2*(x1*(y2-y3)+x2*(y3-y1)+x3*(y1-y2))
   xu = ((x1*x1+y1*y1)*(y2-y3) + (x2*x2+y2*y2)*(y3-y1) + (x3*x3+y3*y3)*(y1-y2)) / d
   yu = ((x1*x1+y1*y1)*(x3-x2) + (x2*x2+y2*y2)*(x1-x3) + (x3*x3+y3*y3)*(x2-x1)) / d
   r1 = math.sqrt((x1-xu)*(x1-xu) + (y1-yu)*(y1-yu))
   r2 = math.sqrt((x2-xu)*(x2-xu) + (y2-yu)*(y2-yu))
   r3 = math.sqrt((x3-xu)*(x3-xu) + (y3-yu)*(y3-yu))
   r = (r1+r2+r3)/3
   #pdb.gimp_message('Radius is'+str(r)+' center at'+str(xu)+','+str(yu))
   # Draw circle.
   # Perimeter is 2*PI*r, we use just more pixels to have subsampling, like 12*r
   number_of_pixels = int(12 * r)
   for i in range(0, number_of_pixels):
      angle = math.pi * 2 * i / number_of_pixels
      x = xu + r * math.cos(angle)
      y = yu + r * math.sin(angle)
      xi = int(x + 0.5)
      yi = int(y + 0.5)
      if xi >= 0 and xi < newLayer.width and yi >= 0 and yi < newLayer.height:
         newLayer.set_pixel(xi, yi, (255, 0, 0, 255))

def drawcircle(img, layer) :
   ''' Draws a circle around three marked pixels
   
   Parameters:
   img : image The current image.
   layer : layer The layer of the image that is selected.
   '''
   # Indicates that the process has started.
   gimp.progress_init("Drawing circle " + layer.name + "...")

   # Set up an undo group, so the operation will be undone in one step.
   pdb.gimp_image_undo_group_start(img)

   # Get the layer position.
   pos = 0;
   for i in range(len(img.layers)):
      if(img.layers[i] == layer):
         pos = i
   
   # Create a new layer to save the results (otherwise is not possible to undo the operation).
   newLayer = gimp.Layer(img, layer.name + " with circle", layer.width, layer.height, RGBA_IMAGE, layer.opacity, layer.mode)
   img.add_layer(newLayer, pos)
   layerName = layer.name
   
   # Clear the new layer.
   pdb.gimp_edit_clear(newLayer)
   newLayer.flush()
   
   try:
      markerpixels = []
      # fast pixel access, direct access is DEAD SLOW
      srcRgn = layer.get_pixel_rgn(0, 0, layer.width, layer.height, False, False)
      src_pixels = array.array("B", srcRgn[0:layer.width, 0:layer.height])
      p_size = len(srcRgn[0,0])
      # we can access the region as well...
      index = 0
      for ty in range(layer.height):
         for tx in range(layer.width):
            pixel = src_pixels[index : index + p_size]
            index += p_size
            if pixel[0] == markercolor[0] and pixel[1] == markercolor[1] and pixel[2] == markercolor[2]:
               markerpixels += [(tx, ty)]
               
      # Compute circle center and radius from 3 or 6 points (sorted along X)
      markerpixels = sorted(markerpixels, key=lambda x: x[0])
      if len(markerpixels) >= 3:
         render_circle(newLayer, markerpixels)
         # second circle
         if len(markerpixels) >= 6:
            render_circle(newLayer, markerpixels[3:])

      # Update the new layer.
      newLayer.flush()
      newLayer.merge_shadow(True)
      newLayer.update(0, 0, newLayer.width, newLayer.height)
   except Exception as err:
      gimp.message("Unexpected error: " + str(err))
   
   # Close the undo group.
   pdb.gimp_image_undo_group_end(img)
   
   # End progress.
   pdb.gimp_progress_end()

register(
   "python_fu_drawcircle",
   "Draw circle",
   "Finds three pixels with defined color (#FF00FF) and draws a circle around them.",
   "Thorsten Jordan",
   "Open source (GPL v2)",
   "2018",
   "<Image>/Filters/drawcircle",
   "RGB, RGB*",
   [],
   [],
   drawcircle)

main()
Dateianhänge
kreistiller.jpg
Kreistiller Anzeigebeispiel

Antworten

Zurück zu „Bogenbau“