Image Manipulation
Re: Image Manipulation
Sheesh. I'm drawing to draw a circle in Gimp and you'd think that'd be easy.
No.
I had to find a tutorial on it and it's mad hard for how easy it should be.
http://www.farcrydesign.com/tutorials/G ... orial.html
No.
I had to find a tutorial on it and it's mad hard for how easy it should be.
http://www.farcrydesign.com/tutorials/G ... orial.html
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: Image Manipulation
To draw a circle in Gimp, you only need to create a circular selection of the right size, then "Stroke Selection".
To draw anything out of straight lines, I usually just use the paths tool and then "Stroke Path".
... If you need to use mainly straight lines etc for something, then a vector graphics application will perhaps be better suited, like Inkscape.
http://www.inkscape.org
To draw anything out of straight lines, I usually just use the paths tool and then "Stroke Path".
... If you need to use mainly straight lines etc for something, then a vector graphics application will perhaps be better suited, like Inkscape.
http://www.inkscape.org
Re: Image Manipulation
why can't i just have a damn circle and line tool?
"submit a patch" - a developer
"FUCK YOU" - a typical frustrated end user
"submit a patch" - a developer
"FUCK YOU" - a typical frustrated end user
i should not be here
Re: Image Manipulation
filters->render->gfig might be easier. Although the location of the tool is not so intuitive.Baker wrote:Sheesh. I'm drawing to draw a circle in Gimp and you'd think that'd be easy.
No.
I had to find a tutorial on it and it's mad hard for how easy it should be.
http://www.farcrydesign.com/tutorials/G ... orial.html
-
toneddu2000
- Posts: 1395
- Joined: Tue Feb 24, 2009 4:39 pm
- Location: Italy
Re: Image Manipulation
I really suggest you, as goldenboy said, to use Inkscape for this kind of works
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Re: Image Manipulation
Inner mysteries to unravel:
1) Flood fill
2) Edge detection
3) Complex selection
In a way those aren't hard. In a way, they require a bit of efficiency. And they are all related.
Input: For instance, let's say there is an image with a solid white background color.
Output: Let's say you wish to change that background color to green.
In theory ...
1) Generate an alpha mask with alpha = black (not solid) for areas of the background color and ...
2) alpha = white (solid) for areas not touching any area next to the background color and ...
3) an alpha scale for areas bordered by either of the above in proportion to how many or 8 maximum neighboring pixels (top, right, bottom, left, top right, top left, bottom right, bottom left ... but edge of image pixels do not have all of these) are of each type.
4) Then again, some of the neighboring pixels may be other bordering pixels.
1) Flood fill
2) Edge detection
3) Complex selection
In a way those aren't hard. In a way, they require a bit of efficiency. And they are all related.
Input: For instance, let's say there is an image with a solid white background color.
Output: Let's say you wish to change that background color to green.
In theory ...
1) Generate an alpha mask with alpha = black (not solid) for areas of the background color and ...
2) alpha = white (solid) for areas not touching any area next to the background color and ...
3) an alpha scale for areas bordered by either of the above in proportion to how many or 8 maximum neighboring pixels (top, right, bottom, left, top right, top left, bottom right, bottom left ... but edge of image pixels do not have all of these) are of each type.
4) Then again, some of the neighboring pixels may be other bordering pixels.
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: Image Manipulation

I'd used my "have C allocate and return an array list" code plus some geometry calculations and reuse of verts with triangle fans.
I'm using a single line to draw each polygon.
Code: Select all
ScreenRect region= { {25, 25}, {225, 225} };
GL_Draw_Polygon_Inscribed(region, 5, Color_RGBA_From_Bytes(255, 0, 0, 255));Code: Select all
void GL_Draw_Polygon_Inscribed (ScreenRect location, int numSides, unsigned RGBAcolor)
{
float center_x = ScreenRect_CenterXf (location);
float center_y = ScreenRect_CenterYf (location);
float circumradius = ScreenRect_CircumRadiusf (location);
Point2D** pointsList = Polygon_Vertices_ArrayListAlloc (numSides, center_x, center_y, circumradius);
const int numPointsList = ArrayListCount (pointsList);
color4_t RGBAColor4f;
Color_RGBA_To_Color4f (RGBAcolor, RGBAColor4f);
GL_Prepare_Colored_ListVerts (pointsList, numPointsList, GL_TRIANGLE_FAN, RGBAColor4f);
glLineWidth(3);
GL_Prepare_Colored_ListVerts (pointsList, numPointsList, GL_LINE_LOOP, COLOR4F_WHITE);
glLineWidth(1);
glPointSize(8);
GL_Prepare_Colored_ListVerts (pointsList, numPointsList, GL_POINTS, COLOR4F_YELLOW);
glPointSize(6);
GL_Prepare_Colored_ListVerts (pointsList, numPointsList, GL_POINTS, COLOR4F_LITERED);
glPointSize(1);
ArrayListFree (pointsList);
}Code: Select all
Point2D** Polygon_Vertices_ArrayListAlloc (int numSides, float center_x, float center_y, float circumradius)
{
Point2D myPolygons[numSides];
const float pieSlice = 360 / numSides;
float degrees = 90;
for (int side = 0; side < numSides; degrees += pieSlice, side ++)
{
float x = -1, y = -1;
Circle_Set_Point_With_Center_Radius_Degrees (&x, &y, 0, 0, circumradius, degrees);
myPolygons[side].x = center_x + x;
myPolygons[side].y = center_y - y; // True geometry flips Y, we need descending Y or whatever
}
ReturnArray_Alloc (Point2D**, myPolygons);
}Code: Select all
void pArrayFree (void** arrayList)
{
Memory_free (*arrayList);
Memory_free (arrayList);
}
int pArrayCount (void** arrayList)
{
int count;
for (count = 0; arrayList[count]; count ++ )
;
return count;
}
void** pReturnArray (const void* sourceItems, const size_t numItems, const size_t itemSizeBytes)
{
void* myReturnData = Memory_calloc (numItems + 0, itemSizeBytes, "Array data"); // Malloc return data block
void** myReturnPointer = Memory_calloc (numItems + 1, sizeof(myReturnData), "Array of pointers"); // Malloc return pointer block
myReturnPointer[numItems] = NULL; // NULL terminate list
for (int n = 0; n < numItems; n++)
{
size_t addy = n * itemSizeBytes;
memcpy (&myReturnData[addy], &sourceItems[addy], itemSizeBytes);
myReturnPointer[n] = &myReturnData[addy];
}
return myReturnPointer;
}
// Creation
void** pReturnArray (const void* sourceItems, const size_t numItems, const size_t itemSizeBytes);
// Utilization
int pArrayCount (void** arrayList);
#define ArrayListCount(arrayList) pArrayCount((void**)arrayList) // Warning free
// Destruction
void pArrayFree (void** arrayList);
#define ArrayListFree(arrayList) pArrayFree((void**)arrayList) // Warning free
#define ReturnArray_Alloc(type, array) { \
const int sizeOfItem = sizeof(array[0]); \
const size_t numItems = sizeof(array)/sizeOfItem; \
return (type)pReturnArray(array, numItems, sizeOfItem ); \
}Code: Select all
void Circle_Set_Point_With_Center_Radius_Degrees (float *out_x, float *out_y, float center_x, float center_y, float radius, float degrees)
{
const float radians = DEGREES_TO_RADIANS(degrees);
*out_x = cosf(radians) * radius + center_x;
*out_y = sinf(radians) * radius + center_y;
}The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: Image Manipulation
But there is another valid question. What good are platform neutral image manipulation functions without a platform neutral interface.
I think GTK looks ugly and all 1990s like Java's crappy looking interface. I think playing in some platform's "only me" sandbox is ... dumb ... even if you like the platform. The "my platform sandbox" where my platform might be Microsoft or Apple or X11 isn't the solution to the problem, it IS the problem.
But there are no solutions.
But I've been working on that one too. Dwelling on how "controls" and "forms" work on Windows and thinking about vb6 and such. And doing it possibly better.
The above macros can be redefined 3 times recursively 
Pass 1: Create struct ... goes like this ...
Pass 2: Actually generate property GET and SET. And READ and WRITE. If I have read and write, I can create controls via a "Quake console" with a command or write the "form" to file.
Pass 3: Create a fixed array of values of string plus 2 functions. The 2 functions interpret a string based on datatype (one for read, one for write) and can check that the value makes any sense.
Then give each type of control a draw function, mouse/touch event function and key press function.
Let the "form" that holds all of these things know what field has "focus"
And boom! At least for drawing: You have maybe 75% of vb6 form creation functionality, plus you can write it to file FAR better and even add controls in real time.
Mouse input: Going to have to plan that.
I think GTK looks ugly and all 1990s like Java's crappy looking interface. I think playing in some platform's "only me" sandbox is ... dumb ... even if you like the platform. The "my platform sandbox" where my platform might be Microsoft or Apple or X11 isn't the solution to the problem, it IS the problem.
But there are no solutions.
But I've been working on that one too. Dwelling on how "controls" and "forms" work on Windows and thinking about vb6 and such. And doing it possibly better.
Code: Select all
PROPERTY_LIST_START
PROPERTY_FIELD (controltype, controlType ); // Intended location x1, y1 and x2, y2
PROPERTY_FIELD (ScreenRect, origin ); // Intended location x1, y1 and x2, y2
PROPERTY_FIELD (fbool, hidden );
PROPERTY_FIELD (fbool, notFocusable );
PROPERTY_ARRAY (char, 64, name );
PROPERTY_ARRAY (char, 256, text );
PROPERTY_FIELD (size_t, textMaxBytes );
PROPERTY_FIELD (float, value );
PROPERTY_FIELD (float, valueMin );
PROPERTY_FIELD (float, valueMax );
PROPERTY_ARRAY (char, 64, bundleURL );
PROPERTY_FIELD (color4byte, foregroundColor );
PROPERTY_FIELD (color4byte, backgroundColor );
PROPERTY_FIELD (color4byte, contentsForeColor );
PROPERTY_FIELD (color4byte, contentsBackColor );
PROPERTY_FIELD (int, borderWidth );
PROPERTY_FIELD (int, tabIndex );
PROPERTY_RUNTIME (ScreenRect, runtime_absOrigin );
PROPERTY_RUNTIME (ScreenRect, runtime_hotspot );
PROPERTY_RUNTIME (imageRGBA_t, runtime_image );
PROPERTY_RUNTIME (texture_t*, runtime_textureBoss );
PROPERTY_RUNTIME (charset_t*, runtime_charset );
PROPERTY_RUNTIME (texture_t*, runtime_textureBoss );
PROPERTY_RUNTIME (size_t, runtime_textStrlength );
PROPERTY_RUNTIME (size_t, runtime_textCursor );
PROPERTY_RUNTIME (size_t, runtime_textSelectionStart );
PROPERTY_RUNTIME (size_t, runtime_textSelectionLength );
PROPERTY_RUNTIME (size_t, runtime_textFirstVisibleCol );
PROPERTY_LIST_ENDPass 1: Create struct ... goes like this ...
Code: Select all
#define PROPERTY_FIELD(datatype, propertyname) datatype* propertyname; datatype _##propertyname
#define PROPERTY_ARRAY(datatype, size, propertyname) datatype* propertyname; datatype _##propertyname[size]
#define PROPERTY_RUNTIME(datatype, propertyname) datatype* propertyname; datatype _##propertynameCode: Select all
#define PROPERTY_SYNTHESIZE(propertyname, datatype) \
void Property_Set_##propertyname (exControl* myControl, datatype value); \
\
void Property_Set_##propertyname (exControl* myControl, datatype value) \
{ \
myControl->_##propertyname = value; \
myControl->propertyname = &myControl->_##propertyname; \
}Then give each type of control a draw function, mouse/touch event function and key press function.
Let the "form" that holds all of these things know what field has "focus"
Code: Select all
// A collection of controls
typedef struct exForm_s
{
// Run time properties
exControl controls[256]; // A set of 256 max controls. Form is control 0
int numControls; // We might not use this for anything.
exControl* myself; // This form as a control for others to inherit from where property isn't specified?
exControl* focus; // NULL for none?
exControl* drawFirst; // Linked list header. Should we ever save to disk, save using this as the order.
} exForm;Mouse input: Going to have to plan that.
The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Re: Image Manipulation
I've got most of what vb6 does that matters written in about 5 files. More to do. Might take a few weeks for anything of interest to materialize from this due to lack of time.
But these 5 files are laughably short. Like "haha funny like a clown" short. A few functions of 10-12 lines here, a 6 line one there. And it can read/write properties into a nice and short text file that looks like this:
Since this understands text, a new on-screen control could be created from, say, the console in Quake. And display the properties via a console command. The key was just writing 3 creative macros to reuse data: the macros automatically write property set/read/write functions based on data type, create a property name to property read/write function table lookup (so a text name can be associated with a text-input function).
Macros output stuff like
but from a simple data source.
But these 5 files are laughably short. Like "haha funny like a clown" short. A few functions of 10-12 lines here, a 6 line one there. And it can read/write properties into a nice and short text file that looks like this:
Code: Select all
controlType:Form
controlType:Rect origin:25,25,100,100 backgroundColor:#ffcc33
controlType:Rect origin:0,125,100,225 backgroundColor:#800000 foregroundColor:#ff0000
controlType:Rect origin:125,0,325,150 backgroundColor:#00ff00Macros output stuff like
Code: Select all
typedef enum {DESIGN_TIME, RUN_TIME, } propavail;
typedef fbool (*property_read_t)(exControl*, const char*);
typedef fbool (*property_write_t)(exControl*, char*);
// propertytable propertyTable [] =
// {
//
// {"controlType", Property_Read_controlType, Property_Write_controlType , DESIGN_TIME },
// {"origin", Property_Read_origin, Property_Write_origin , DESIGN_TIME },
// {"hidden", Property_Read_hidden, Property_Write_hidden , DESIGN_TIME },
// {"notFocusable", Property_Read_notFocusable, Property_Write_notFocusable , DESIGN_TIME },The night is young. How else can I annoy the world before sunsrise?
Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..