GIMP Script-Fu: "Error: <: argument 1 must be: number" - scheme

I'm having an issue with writing a GIMP Script that applies a drop shadow. So this is how the script looks when you pull it from the console:
(script-fu-drop-shadow run-mode image drawable value value value color value toggle)
And these are the values I've entered:
(script-fu-drop-shadow 1 image layer 0 0 3 '(115.9 200.9 245.1) 1 0)
When I try to run it, I get the following error:
Execution error for 'MUA Portrait Outline - Blue Glow':
Error: <: argument 1 must be: number
I think I'm not really understanding all the values that I need to enter.
run-mode is straightforward, since it says to either use 1 or 0.
Based on prior scripts I've tried, I'm pretty sure that I leave image as image since it's just for the current image.
I'm not too sure what drawable is, but I read that drawables include layers, so I put layer. Not sure if that's accurate.
The next 3 value variables are for the x offset, y offset, and blur radius. Straightforward.
I'm not too sure if I'm entering color correctly as I've never actually used a script that asks for the color, but I think I did it correctly just based on some research I did online.
The last value variable is also straightforward, as it's the opacity of the shadow.
I have no clue what to set for toggle. It says it accepts INT32 for that, so I figured I would just put 0. I tried to do some online research, but I couldn't find anything
Any help would be greatly appreciated! I'm not well-versed in Script-fu. I've tried a few things here and there, but I don't know much formal stuff. Feel free to explain things as simply as possible :)

You have to find numbers of current image and current drawable (if you are working with multiple images, these don't have to be 1 and 3), then call it without run-mode:
> (gimp-image-list)
(1 #(1)) <-- All images, current image is one number from vector #(1)
> (gimp-image-get-active-drawable 1)
(3) <-- Current drawable of current image
> (script-fu-drop-shadow 1 3 0 0 20 '(255 0 0) 100 0)
(#t)
If you don't know meaning of some arguments, you can check Procedure Browser (Help → Procedure Browser)- toggle argument is Allow resizing and you can also use TRUE or FALSE as value, because they evaluate to 1 or 0 respectively.
EDIT: If you want run this as .scm script, follow these steps:
.scm file should look like this:
(define (script-fu-my-script image drawable)
(script-fu-drop-shadow image drawable 0 0 20 '(255 0 0) 100 0))
(script-fu-register "script-fu-my-script"
_"Add _Drop _Shadow..."
_"Add drop shadow"
"Author's name"
"Author's name"
"12/9/21"
"*"
SF-IMAGE "Input image" 0
SF-DRAWABLE "Input drawable" 0)
(script-fu-menu-register "script-fu-my-script"
"<Image>/My_Scripts/Drop")
Find correct folder for your scripts: Edit -> Preferences -> Folders -> Scripts and move your .scm file to one from these folders.
Restart GIMP or refresh your scripts: Filters -> Script-Fu -> Refresh Scripts
Right click on image, My Scripts -> Drop -> Add Drop Shadow.

It works if you drop the run-mode argument.
(script-fu-drop-shadow 1 3 3 3 3 '(115 200 245) 50 0)
Don't ask me why, I write my scripts in Python :)
For that matter most of the code in that script is handling things that mostly make sense when using it interactively. In most case your code can do it by selecting alpha, adding a layer, filling the selection, blurring it and adjusting the offset.

Related

Gimp Script-Fu: Delete a selection

I'm trying to write a script for Gimp that will crop an image, make a circular selection of what's left, invert the selection, and then delete the selection. I have the cropping, selection, and inversion part done, but the deleting is what's getting me.
(removed old code, see update)
That's the code I have. What's confusing me about the gimp-item-delete code is the item. I understand that I need to define my current selection as the item, but I'm not sure how to do this. If someone could explain how to do this, I would greatly appreciate it! Alternatively, if there's an easier way to do what I'm trying to do (but preferably still in a script), please let me know what you think. My knowledge of this coding is pretty limited, so simple explanations are appreciated.
UPDATE/EDIT:
Here's the (full) updated code:
; XML2 Conversation Portrait Preview Crop
(define (script-fu-xml2-convo-preview image layer)
(gimp-image-undo-group-start image)
(gimp-selection-none image)
(gimp-image-resize image 152 152 -280 -496)
(gimp-layer-resize-to-image-size layer)
(gimp-image-select-ellipse image 0 0 0 152 152)
(gimp-selection-invert image)
(gimp-displays-flush)
(gimp-drawable-edit-clear layer)
(gimp-selection-none image)
(gimp-image-undo-group-end image)
)
; populate script registration information
(script-fu-register
"script-fu-xml2-convo-preview"
"XML2 Conversation Portrait Preview Crop"
"Crops the preview window for XML2 conversation portraits."
"BaconWizard17"
"BaconWizard17"
"September 2021"
"*"
SF-IMAGE "Image" 0
SF-DRAWABLE "Layer" 0
)
; register the script within gimp menu
(script-fu-menu-register "script-fu-xml2-convo-preview" "<Image>/Marvel Mods/Skin Previews/XML2 PC")
So when I'm running this script, it appears to just crop it and doesn't delete the inverted circular selection. However, if I interact with the image in any way (click on it, duplicated it, copy/paste it, undo/redo), it will correct itself and show the properly cropped image with the deleted circular corners. When I first run the script, it also shows the incorrect image up at the top where you can pick which image you're working on, but after interacting with the image it will show the correct image. Here's an example:
The starting image that I create from the clipboard with Ctrl+Shift+V (after screenshotting it from the game using PrtScr):
Then, I run the script, which results in this:
At the top of the screen, the image shows up like this (which is the top left 152x152 pixels of the starting image:
How the image looks once I interact with it in any way (clicking on it, copy/pasting it, duplicating it, undoing/redoing the operation):
The thumbnail at the top of the screen after I interact with the image:
Maybe it's getting hung up on something during the operation? I'm not sure. I understand if this issue is unavoidable, but I would prefer to be able to just run the script and move on rather than having to interact with the image to get it to show up correctly. The image does have an alpha layer when it's pasted in.
gimp-item-delete is a memory/object management thing and is rarely used. What you are looking for is gimp-drawable-edit-clear.
Note that it should be done (together with your final gimp-selection-none) before gimp-image-undo-group-end if you want your whole script to be undone by a single Ctrl-Z.
Edit: It appears that your code works, it's just that the display isn't updated to show the result, which is exactly what gimp-display-flush is meant to do, so why is your code calling it before gimp-drawable-edit-clear? gimp-display-flush ought to be about the last thing done by your script.

How to convert image to table

I have an image of a table (in my case .gif) and want to extract the table it was (ideally, .ods).
Is there any way to do so? (doing it manually is discarted, since the table has more than 1000 rows and 6 columns)
Here is a part of the image / table:
You will be able to get most of it through OCR, but you'll need to manually verify the data and fix some inaccuracies that will be there. It definitely won't be perfect.
First thing to do is to ensure you have a good quality image for the OCR software:
Here's what I did with your sample png (I'm using Windows):
I opened the image in The Gimp.
Removed the orange/blue backgrounds:
a) Select -> By Color and clicked the blue background
b) I held down Shift and clicked the orange background (this will add it to the current selection)
c) Edit -> Fill With BG Color (this sets it to white)
d) Ctrl-Shift-A to cancel the selection
I removed the partially cut off '305' line:
a) used the Rectangular Select tool button from the palette, and filled the selection with BG Color, as above
Let's remove the table border:
a) Click the 'Fuzzy Select' tool button from the palette
b) Click somewhere on the table border (you should see the 'marching ants' instead of the border)
c) Edit -> Fill With BG Color
d) Ctrl-Shift-A to cancel the selection again
We need to increase the number of pixels that the numbers use so that the OCR can better detect their shapes
a) Image -> Scale Image. I chose to scale by 1000% with Linear Interpolation (the other interpolations won't work as well)
Download and install Tesseract from GitHub
a) At the command prompt type (include the double-quotes to cope with spaces within the path, & change your paths as necessary):
"D:\Program Files (x86)\Tesseract-OCR\tesseract" "d:\temp\your_image.png" "d:\temp\your_txt_file_output"
The output with be a text file with an appended .txt extension. It will still have a few artifacts but we can easily correct those in Notepad++ (or similar):
a) The commas were seen as full-stops, so I did a Find and Replace of "." with "," (I'm assuming you don't have any decimal points in the data!)
b) There were some spaces before a few commas, so I did Find and Replace " ," with "," (note I included a space before the comma in the Find)
c) There were still some spaces in the numbers, so I did a Find and Replace of " " with "" (a space with an empty replace)
This gave the following result:
298 299 300 301 302 303 304
910,820,000 920,820,000 930,820,000 941,820,000
952,820,000 983,820,000 9?4,820,000 210,000
220,000 220,000 220,000 220,000 220,000
220,000 2,500 2,500 3,000 3,000
3,000 3,000 3,000 19,000 19,000
20,000 20,000 20,000 20,000 20,000
Note the question mark in the place of 7 in the second block of text. Things like that still need to be tidied up.
Lastly, you'd copy and paste the rows of text into your spreadsheet etc.
I wanted to post another option I finally found online.
https://convertio.co/es/ocr/
Even though I think K Scandrett answer deserves to be the correct one, since it doesn't rely on a URL, which might go down.
If this is a one-time/rare need and you are windows OS user and you have a Microsoft Excel installed, the application supports extracting the image data to excel. Follow this link for the complete reference.

corona sdk button's images not visible/misplaced

I just installed the sdk and run in creating sample app project.
I ended up with a folder full of icons and 3 classes that were to show me how things work.
The problem I noticed is that the code creates buttons that should have a background image but only the text is visible. Images are in the same folder and spelling is correct.
The auto-generated code looks like this:
playBtn = widget.newButton{
label="Play Now",
labelColor = { default={255}, over={128} },
default="button.png",
over="button-over.png",
width=154, height=40,
onRelease = onPlayBtnRelease -- event listener function
}
playBtn.x = display.contentWidth*0.5
playBtn.y = display.contentHeight - 125
Also the text doesn't change color. When I added another button below with my image below the auto created one I was able to see my tiny part of my image in the top left corner. The button was also visible when moving to net scene. How come?
To help solve your color issue you need to change the values. Corona recently changed to decimal colors, the range is from 0 to 1 versus 0 to 255. Anything over 1 will result in a 1 being used for the color.
So basically your colors need to be divided by 255 to get the proper value. You can either have the code divide it or you can divide the value yourself. You can read a post about it here.

How can I modify a screensaver (.saver)?

My goal is to be able to modify a Matrix screensaver that is no longer being supported by the developers. I simply want to be able to change the color of the glyphs from green to red. From what I've read, I might need to edit the compiled .nib file. And supposedly, there are tricks to do this.
The only files I see within the .saver file are:
Unix Executable File
InfoPlist.strings
Matrix.nib
a Glyphs.png (its in grayscale, so the color affect must come from programming)
A Matrix.nib file in a folder entitled Japanese.lproj
I don't see any other files that I could edit that would let me achieve this, so I am looking for some guidance.
EDIT: The author posted the source code for his screensaver on his github. Now i'm just trying to figure out exactly what needs to be changed.
The modification of the source code isn't very hard. The colors are computed on the fly, so an asset can't be modified to change the color.
In line 226 of MatrixStrip.m change the 1 before the left bracket to a 0. In Line 228 Change the 0 to a 1. The column below the V in the code.
.... V
226: colorArray[16*i + 4*c + 0] = (cellState[i] == 0) ? 0.0 : g;
227: // Cells which are very bright are slightly whitened
228: colorArray[16*i + 4*c + 1] = ((g > 0.7) && (cellState[i] != 0)) ? (g - 0.6) : 0.0;
Make the same change to lines 253 and 255. You are putting the numbers in column column 34 in the inner loops in order. In the original code, reading down column 34 the numbers a 1, 0, 2, 3. This has to be done in both of the inner loops on the 4 lines I indicated. These numbers are the indices to the RGBA color.
I'm not sure if my explanation is adequate, so instead of expanding this to 1000 words, I'll include a screen shot of the diff with the relevant parts highlighted by Kaleidoscope. The original code is on the left.
I had to download the image to see the relevant details.

Smooth PostScript animations

I would like to run animations in PostScript smoothly. To see what I want, let me switch to PostScript directly. Call ghostscript, and
200 dup scale .5 setgray 0 0 3 3 rectfill
We have now a gray square.
0 setgray 0 1 3 1 rectfill
With a black stripe in it. We will now fill that stripe, one time white
and black in succession:
{1 setgray 0 1 3 1 rectfill 0 setgray 0 1 3 1 rectfill} loop
You will see now some flickering of black and white rectangles that
are smaller than the original black stripe. Ideally, we would see
the original grey square. Or almost. Where can I get such functionality today?
To see a more interesting animation sequence searching for magic
squares of size 5:
wget http://www.complang.tuwien.ac.at/ulrich/gupu/l5.eps.gz
zcat l5.eps.gz | ghostscript -
A couple of years ago I did try to address these issues. But it never went into ghostscript or Xfree. See
this page. Maybe there are some better ideas now?
Edit: After reading the responses so far, let me clarify one issue here. Essentially, there are two independent issues in this question:
How should an animation be viewed from the language level? I believe, the best way is to view each frame as a single page. With copypage incremental changes can be realized with low effort. Sadly, that semantics of copypage is only present in Level 1 and 2. In Level 3, the meaning of copypage changed to showpage. I did - many years ago - a little modification to ghostscript to delay all visible changes up to copypage or showpage. In this manner, a single XCopyArea containing the changed area is performed locally on the server (that is, the display).
How should actual changes on the visual display be synchronized to avoid artefacts that where not present in the graphics described? The irregular flicker you see is not a privilege of PostScript, it seems to be present in any double-buffered system I have seen so far. Just try to program this in whatever system you see fit.
Further edit:
To get the right language level, that is level 1 or 2 do (for ghostscript):
systemdict /.setlanguagelevel known {2 .setlanguagelevel} if
Edit: I am adding this comment to may attract some new postscript contributors.
We explored some of these issues in this thread on comp.lang.postscript.
Since the release of the Level 2 standard, Postscript is a garbage-collected language. You can disable collection of user objects with the fragment -2 vmreclaim, but it doesn't accomplish much. You can disable ALL ghostscript garbage collection by invoking with the -dNOGC option. This should help prevent stalling and spitting with parts of the image.
Ghostscript has a non-standard operator called flushpage, which synchronizes the rendering with the execution. This helps make sure that everything is seen before it's gone.
- flushpage -
On displays, flushes any buffered output, so that it is guaranteed to
show up on the screen; on printers, has no effect
And for timing control, there doesn't seem to be a better way than simple busy-waiting.
/smallpause {
/flushpage where{pop flushpage}if
50 sleep } def
/pagepause {
/flushpage where{pop flushpage}if
1000 sleep } def
/sleep {
usertime add {
10 {
1 100000 div pop %busy
.1 sin 257 cos atan pop %busy busy
} repeat
dup usertime le {exit}if
} loop pop
} def
The where guards around flushpage allow you to send the same code to interpreters other than ghostscript (like a printer).
If you had an actual Display Postscript server, you could use the wait operator instead of busy-waiting.
Although I like (and upvoted) #luserdroog's answer, I don't believe Postscript should be used for animations on this way - I'd rather use some language that can run widgets or display elements that are designed for real time display and user interation - that is not the case of postscript or ghostscript.
I think it would be nice, though, use postscript for aimations for rendering purposes - just rendering a page after each modification on the image, and using an external program to assemble the different pages as animation frames.
Maybe even using postscript as a rendering engine, with the process in another language calling ghostscript to render each frame in realtime. A nice and easy to use multimedia framework to do that could be for example, the Python language with the Pygame module.
Here is a short example using "pure python + pygame".
#! /usr/bin/env python
# coding: utf-8
import pygame
size = 640,480 #(in pixels)
# multiplying factor so that the whole image is 5 units across
factor = size[0] / 5.0
# Inits pygame drawing window
screen = pygame.display.set_mode(size)
# Rectangle drawing function that scales drawing using the factor above
def draw_rect(color, rect):
new_rect = [int (r * factor) for r in rect]
return pygame.draw.rect(screen, color, new_rect)
def main():
draw_rect((128,128,128), (0, 0, 3, 3))
colors = ((255,255,255), (0,0,0))
color_index = 0
while True:
draw_rect(colors[color_index], (0, 1, 3, 1))
pygame.display.flip()
color_index = 1 - color_index
pygame.time.delay(50) # in miliseconds
try:
main()
finally:
pygame.quit()
To execute this, you have to have Python and Pygame (from http://pygame.org - there are ready packages on most linux systems for that)
Pygame's drawing API is much poorer than postscript - if you need more than rectangles
(like bezies, scaling, rotating and shearing the coordinate system, and so on), the way to go is to use Cairo + python + some display library (which might be pygame, GTK+ or qt) . Cairo is a 2D drawing library that inherits from the postscript way. - or, as I said above, to drive a ghostscript external process using Python, having it generating a rle compressed image file to stdout or a ramdrive, and that image read and displayed frame by frame using python + pygame.
Another option is to use HTML5's Canvas, and do everything in Javascript, viewable on a browser. HTML5's Canvas also inherits the Postscript way of drawing.

Resources