Skip to content

Instantly share code, notes, and snippets.

@Draco18s
Created May 2, 2024 05:50
Show Gist options
  • Save Draco18s/5b1ace17b590d17c2efc50b31b75fedd to your computer and use it in GitHub Desktop.
Save Draco18s/5b1ace17b590d17c2efc50b31b75fedd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
# Gimp-Python - allows the writing of Gimp plugins in Python.
# Copyright (C) 2024 draco18s <draco18s(at)gmail.com>
#
# 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 3 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.
# This code is slow as balls, its your own fault if you use this.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
from gimpfu import *
import time
gettext.install("gimp20-python", gimp.locale_directory, unicode=True)
def gimp_log(text):
pdb.gimp_message(text)
def pixel_skew(img, layer, skew_angle):
layer = skew_x(img, layer, skew_angle)
layer = skew_y(img, layer, skew_angle)
layer = skew_x(img, layer, skew_angle)
def skew_x(img, layer, skew_angle):
skew_angle = skew_angle / 180 * 3.1415
# Get the image's width and height
width = layer.width
height = layer.height
A=-math.tan(skew_angle/2)
# B=math.sin(skew_angle)
centerX = (width/2)+0.5
centerY = (height/2)+0.5
readRegion=layer.get_pixel_rgn(0, 0, layer.width, layer.height)
pixRead=readRegion[:,:]
xoffset = centerY * A
if xoffset < 0:
xoffset = -xoffset
nWidth = int(width + xoffset * 2)
# pdb.gimp_message('New width: %s' % (nWidth))
nHeight = height
# layer_one = img.layer(img, "Skew", nWidth, nWidth, RGB_IMAGE, 100, NORMAL_MODE)
layer_one = gimp.Layer(img, "Skew Layer", nWidth, nHeight)
img.add_layer(layer_one,0)
writeRegion=layer_one.get_pixel_rgn(0, 0, nWidth, nHeight)
pixWrite=writeRegion[:,:]
# Apply the transformation to each pixel in the layer
for y in range(layer.height):
for x in range(layer.width):
# pdb.gimp_message('Getting pixel at index x,y: (%s,%s)' % (x,y))
pixel = readRegion[x,y]
v = (y-centerY) * A
#if v < 0:
#v = v + 0.01
# pdb.gimp_message('Setting pixel at index x,y: (%s,%s)' % ((x + int(v + xoffset)) % nWidth,y))
writeRegion[(x + int(v + xoffset)) % nWidth,y] = pixel
return layer_one
def skew_y(img, layer, skew_angle):
skew_angle = skew_angle / 180 * 3.1415
# Get the image's width and height
width = layer.width
height = layer.height
# A=-math.tan(skew_angle/2)
B=math.sin(skew_angle)
centerX = (width/2)+0.5
centerY = (height/2)+0.5
readRegion=layer.get_pixel_rgn(0, 0, layer.width, layer.height)
pixRead=readRegion[:,:]
yoffset = centerY * B
if yoffset < 0:
yoffset = -yoffset
nWidth = width
nHeight = int(height + yoffset*2)
layer_one = gimp.Layer(img, "Skew Layer", nWidth, nHeight)
img.add_layer(layer_one,0)
writeRegion=layer_one.get_pixel_rgn(0, 0, nWidth, nHeight)
pixWrite=writeRegion[:,:]
# Apply the transformation to each pixel in the layer
for y in range(layer.height):
for x in range(layer.width):
pixel = readRegion[x,y]
v = (x-centerY) * B
#if v < 0:
#v = v + 0.01
writeRegion[x, (y + int(v + yoffset)) % nHeight] = pixel
return layer_one
register(
"python-fu-pixel_skew",
N_("Performs a pixel perfect skew"),
"Performs a pixel perfect skew",
"Draco18s",
"Draco18s",
"2024",
N_("_Pixel Skew"),
"RGB*, GRAY*",
[
(PF_IMAGE, "image", "Input image", None),
(PF_DRAWABLE, "drawable", "Input drawable", None),
(PF_ADJUSTMENT, "skew", _("Skew angle"), 0, (-180, 180, 1)),
],
[],
pixel_skew,
menu="<Image>/Filters/Distorts",
domain=("gimp20-python", gimp.locale_directory)
)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment