from gimpfu import *

def do_message_box(msg):
    handler = pdb.gimp_message_get_handler()
    pdb.gimp_message_set_handler(MESSAGE_BOX)   #{ MESSAGE-BOX (0), CONSOLE (1), ERROR-CONSOLE (2) }
    pdb.gimp_message(msg)
    pdb.gimp_message_set_handler(handler)

def add_steg_text(image, layer, text):

    length = len(text)
    # limit length of message to 255
    if length > 255:
        do_message_box("text too long! (don't exeed 255 characters)")
        return

    pdb.gimp_image_undo_group_start(image)
    newlayer = layer.copy()
    image.add_layer(newlayer, -1)
    pr = newlayer.get_pixel_rgn(0,0,newlayer.width,newlayer.height)

    for index in range(length+1):
        col = (index) / layer.height
        row = (index) % layer.height
        if index == 0:              #store length in first pixel
            newpixel = chr(length)
        else:                   #store string in subsequent pixels
            newpixel = text[index-1]
        newpixel += pr[col,row][1] + pr[col,row][2]
        if layer.has_alpha:
            newpixel += pr[col,row][3]
        pr[col,row] = newpixel 

    newlayer.flush()
    layer.merge_shadow(True)
    newlayer.update(0, 0, newlayer.width, newlayer.height)

    pdb.gimp_image_undo_group_end(image)
    gimp.displays_flush() 

def read_steg_text(image, layer, outputmode):

    pr = layer.get_pixel_rgn(0,0,layer.width,layer.height)
    length = ord(pr[0,0][0])
    msg = ""
    for index in range(length):
        col = (index+1) / layer.height
        row = (index+1) % layer.height
        msg += pr[col,row][0]

    if outputmode == 0:
        do_message_box("%s" %msg)

register(
    "python_fu_simple_steg_text_add",
    "Adds a simple 'hidden message' to an RGB image",
    "Adds a simple 'hidden message' to an RGB image",
    "",
    "",
    "Version 1.0 (25-3-2015)",
    "Add message",
    "RGB*",
    [
      (PF_IMAGE,    "image",    "Input image", None),
      (PF_DRAWABLE, "drawable", "Input layer", None),
      (PF_STRING,   "text",     "Text:",       "")
    ],
    [],
    add_steg_text,
    menu="<Image>/MyScripts/Steg/Text Steganography")

register(
    "python_fu_simple_steg_text_read",
    "Reads a simple 'hidden message' added to an RGB image",
    "Reads a simple 'hidden message' added to an RGB image",
    "",
    "",
    "Version 1.0 (25-3-2015)",
    "Display message",
    "RGB*",
    [
      (PF_IMAGE,    "image",    "Input image", None),
      (PF_DRAWABLE, "drawable", "Input layer", None),
      (PF_OPTION,   "outputmode", "Output mode", 0, ("Display in a message box", "None"))
    ],
    [],
    read_steg_text,
    menu="<Image>/MyScripts/Steg/Text Steganography")

main()
from gimpfu import *
#import math, random, os, sys

def do_message_box(msg):
    handler = pdb.gimp_message_get_handler()
    pdb.gimp_message_set_handler(MESSAGE_BOX)   #{ MESSAGE-BOX (0), CONSOLE (1), ERROR-CONSOLE (2) }
    pdb.gimp_message(msg)
    pdb.gimp_message_set_handler(handler)

def hide_image(image, layer, carrier, radix):

    if layer.width > carrier.width or layer.height > carrier.height:
    do_message_box("Carrier image must be at least as large as the image to be hidden!!")
    return

    s = int(radix)

    pdb.gimp_image_undo_group_start(image)
    newlayer = pdb.gimp_layer_new_from_drawable(carrier, image)
    image.add_layer(newlayer, -1)

    gimp.progress_init("Hiding image...")

    ntx = int( (layer.width+63)/64 )            # number of tiles horizontally
    nty = int( (layer.height+63)/64 )           # number of tiles vertically
    for i in range(ntx):
    for j in range(nty):                    # for each tile...
        srcTile = layer.get_tile(False, j, i)
        carTile = carrier.get_tile(False, j, i)
        dstTile = newlayer.get_tile(False, j, i)
        for x in range(srcTile.ewidth):         # for each pixel in tile..
        for y in range(srcTile.eheight):
            spixel = srcTile[x,y]
            cpixel = carTile[x,y]
            r = min(255, ord(cpixel[0]) - (ord(cpixel[0]) % s) + int(s * ord(spixel[0]) / 256))
            g = min(255, ord(cpixel[1]) - (ord(cpixel[1]) % s) + int(s * ord(spixel[1]) / 256))
            b = min(255, ord(cpixel[2]) - (ord(cpixel[2]) % s) + int(s * ord(spixel[2]) / 256))
            dstTile[x,y] = chr(r) + chr(g) + chr(b)
    gimp.progress_update(float(i)/ntx)

    newlayer.flush()
    newlayer.update(0, 0, newlayer.width, newlayer.height)

    pdb.gimp_image_resize_to_layers(image)
    pdb.gimp_image_undo_group_end(image)
    gimp.displays_flush() 

def recover_image(image, layer, radix):

    s = int(radix)

    pdb.gimp_image_undo_group_start(image)
    newlayer = layer.copy()
    image.add_layer(newlayer, -1)

    gimp.progress_init("Recovering image...")

    ntx = int( (layer.width+63)/64 )            # number of tiles horizontally
    nty = int( (layer.height+63)/64 )           # number of tiles vertically
    for i in range(ntx):
    for j in range(nty):                    # for each tile...
        srcTile = layer.get_tile(False, j, i)
        dstTile = newlayer.get_tile(False, j, i)
        for x in range(srcTile.ewidth):         # for each pixel in tile..
        for y in range(srcTile.eheight):
            pixel = srcTile[x,y]
            r = (ord(pixel[0]) % s) * 256 / s
            g = (ord(pixel[1]) % s) * 256 / s
            b = (ord(pixel[2]) % s) * 256 / s
            dstTile[x,y] = chr(r) + chr(g) + chr(b)
    gimp.progress_update(float(i)/ntx)

    newlayer.flush()
    newlayer.update(0, 0, newlayer.width, newlayer.height)

    pdb.gimp_image_undo_group_end(image)
    gimp.displays_flush() 

register(
    "python_fu_simple_steg_hide_image",
    "Hides an RGB image in another RGB image",
    "Hides an RGB image in another RGB image",
    "",
    "",
    "Version 1.0 (2-4-2015)",
    "Hide image",
    "RGB",
    [
      (PF_IMAGE,    "image",    "Input image", None),
      (PF_DRAWABLE, "drawable", "Input layer", None),
      (PF_DRAWABLE, "carrier",  "Carrier image", None),
      (PF_SPINNER,  "radix",    "Radix", 4, (2, 64, 1))
    ],
    [],
    hide_image,
    menu="<Image>/MyScripts/Steg/Image Steganography")

register(
    "python_fu_simple_steg_recover_image",
    "Recovers a 'hidden image' from an RGB image",
    "Recovers a 'hidden image' from an RGB image",
    "",
    "",
    "Version 1.0 (2-4-2015)",
    "Recover image",
    "RGB",
    [
      (PF_IMAGE,    "image",    "Input image", None),
      (PF_DRAWABLE, "drawable", "Input layer", None),
      (PF_SPINNER,  "radix",    "Radix", 4, (2, 64, 1))
    ],
    [],
    recover_image,
    menu="<Image>/MyScripts/Steg/Image Steganography")

main()

Edited 1 Year Ago by jismy jose: this is for image steganography

This article has been dead for over six months. Start a new discussion instead.