What colors are allowed in SpreadsheetGear? - spreadsheetgear

In setting the interior color of a cell, I find that some colors are allowed and some are ignored. For example, this works (where ws is an IWorksheet object):
ws.Cells[r, c].Interior.Color = Colors.LightPink;
but when attempting this color
ws.Cells[r, c].Interior.Color = Color.FromArgb(255, 255, 136, 136);
the result is a cell that still has its original white background. As if the color had never been changed. Are there only certain colors that SpreadSheetGear will allow you to use?

A few years later stumbling on this problem again, I was able to solve it. The list of colors that you are restricted to can be found by inspecting the Colors property of the IWorkbook object:
SpreadsheetGear.IWorkbook wb = SpreadsheetGear.Factory.GetWorkbook();
for (int i = 0; i < wb.Colors.Count; i++)
Debug.WriteLine("[{0}] {1}", i, wb.Colors[i].ToArgb().ToString("x"));
If the color you want is not in this list, then SpreadsheetGear will arbitrarily pick some other color that is in the palette. However, you are able to the colors you want to the palette. For example:
wb.Colors[wb.Colors.Count - 1] = SpreadsheetGear.Colors.Orange;

Related

How to programmatically set color in gimp (pythonfu)?

Using Python, I was able to add a floating text layer using
text_layer = pdb.gimp_text_fontname(image, drawable, x, y, text, border, antialias, size, size_type, fontname)
However, the text appears in black. Specifically pdb.gimp_text_layer_get_color(text_layer) returns RGB (0.0, 0.0, 0.0, 1.0)
I want the font to be in a different color.
I tried
col = gimpcolor.RGB(44.7, 46.7, 58.0)
pdb.gimp_text_layer_set_color(text_layer, col)
Trying pdb.gimp_text_layer_get_color(text_layer) now returns RGB (44.7, 46.7, 58.0, 1.0) but the text in now in white.
How to make the text appear in my desired color or where does gimpcolor object's documentation exist?
The text is created with the current foreground color:
# Two ways to set the color (pick one)
# Color set with the gimp object
gimp.set_foreground(gimpcolor.RGB(0,0,255))
# Color set via PDB API
pdb.gimp_context_set_foreground(gimpcolor.RGB(0,0,255))
text_layer = pdb.gimp_text_fontname(image, None, 100, 100, 'Gimp', 0, True, 80,0, 'Bungee')
Also: careful with number types of the color channels. AFAIK for gimpcolor.RGB(r,g,b):
if the r/g/b argument is a float, it is understood as being in the [0.0 .. 1.0] range (and clamped if outside that range)
if it is an integer, is is understood as being in the [0 .. 255] range
So for instance gimpcolor.RGB(1.,1.,1.) is white (1. = 100%), but gimpcolor.RGB(1,1,1) is nearly black (1/255 = 0.4%).

Is there a way to have google sheets read imperial height as a number?

I'm making a sheet with details about a bunch of fictional characters, and one column I want to have is their height. I would also really like to use Conditional Formatting with a Color Scale to color-code the tallest and shortest characters, and everything in between.
Unfortunately, I live in the US, and am used to height expressed in feet and inches (e.g. 5'10''), which Google Sheets of course does not recognize as a number. Is there any way to remedy this, besides writing everything in terms of just inches (e.g. 60), such that I could apply conditional formatting directly to the column?
I've tried different formats (e.g. 5'10), and I considered having a hidden column with just the inch value and have conditional formatting work off of that row (doesn't work with Color Scale as far as I can tell, since you can't input a custom formula). One thought I had is somehow formatting things as an improper fraction with a denominator of 12, but hiding the denominator? But I have no idea how that would work. I've Googled as best I can, but I haven't found anything (everything's just about changing row height, which makes sense in hindsight).
I understand that you have two goals in mind. First of all, you should decide which unit length to use for managing heights. I have chosen inches, but you could work with feet if you need. This will simplify the scenario and will allow you to work easily with the data, but you could always create a function that translates inches to the foot/inches combo in order to show the data to a third party. This is the example table that I will use:
And this is my code, I will explain it at the bottom:
function main() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
data = sortTable(data);
sheet.getDataRange().setValues(data);
for (var i = 1; i < data.length; i++) {
data[i][2] = gradient(data.length, i);
}
for (var i = 1; i < data.length; i++) {
sheet.getRange(i, 2).setBackground("#" + data[i][2][0] + data[i][2][1] +
data[i][2][2]);
}
}
function sortTable(data) {
data.sort(function(a, b) {
return b[1] - a[1];
})
return data;
}
function gradient(arraySize, position) {
var relativePosition = position / arraySize;
var topColor = [parseInt("00", 16), parseInt("7A", 16), parseInt("33",
16)]; // Green
var bottomColor = [parseInt("FF", 16), parseInt("FF", 16), parseInt("FF",
16)]; // White
var positionColor = [0, 0, 0];
for (var i = 0; i < 3; i++) {
positionColor[i] = Math.floor(topColor[i] * (1 - relativePosition) +
bottomColor[i] * relativePosition).toString(16);
}
return positionColor;
}
First of all you have to read the data with a combination of getValues()/setValues(), and once you do that you can sort the table based on height so you can create the gradient later. Please notice how I separated the sorting function for better clarity.
After that you need the gradient color for setBackground(). To do so I developed a simple linear gradient function that calculates the RGB code from the top to the bottom. In my example the gradient fades from green to white, but you can change it. I also separated the gradient script into its own function. At this point you already have the sorted table and its gradient colors, so you only have to use setValues() and you are done. Feel free to leave any comment if you have doubts about this approach. This would be the final result:
UPDATE
Based in your comments I get that you need an imperial height format. For that case, you could use =INT(B2)&"' "&TRIM(TEXT(ROUND(MOD(B2,1)*12*16,0)/16,"# ??/??")&"""") (assuming that B2 contains the height). This approach will use Sheets Formulas to calculate the remainder part of the height, and its expression as an irreducible fraction. This is the final result:

Given a background and foreground color, how to calculate the mix amount between them in an image?

I have an input image looking like this:
As you can see, it's a restore window icon with a blue tint and a background in a pink color.
There are some pixels which are a mix of both colors by an amount I want to calculate, but don't know how. The 100% background and 100% foreground color is given.
Eventually, I want to create an alpha bitmap in which the RGB amounts of every pixel is the foreground color RGB, but the alpha channel is the mix amount:
I found the answer (myself) after discussing with some mathematicians over at math.stackexchange.
Please read my answer there for the logic behind this; in C#, the code would be like this:
private static double GetMixAmount(Color fore, Color back, Color input)
{
double lengthForeToBack = GetLengthBetween3DVectors(fore, back);
double lengthForeToInput = GetLengthBetween3DVectors(fore, input);
return 1 / (lengthForeToBack / lengthForeToInput);
}
private static double GetLengthBetween3DVectors(Color a, Color b)
{
// Typical length between two 3-dimensional points - simply handle RGB as XYZ!
return Math.Sqrt(
Math.Pow(a.R - b.R, 2) + Math.Pow(a.G - b.G, 2) + Math.Pow(a.B - b.B, 2));
}
If you don't know if the foreground and background colors can really be mixed to result in the input color, make sure to clamp the alpha value to lie between 0.0 and 1.0.

how to optimized this image processing replace all pixels on image with closest available RGB?

Im' trying to replace all pixels of input image with closest available RGB. I have a array contain color and input image. Here is my code, it give me an output image as expected, BUT it take very LONG time( about a min) to process one image. Can anybody help me improve the code? Or if you have any other suggestions, please help.
UIGraphicsBeginImageContextWithOptions(CGSizeMake(CGImageGetWidth(sourceImage),CGImageGetHeight(sourceImage)), NO, 0.0f);
//Context size I keep as same as original input image size
//Otherwise, the output will be only a partial image
CGContextRef context;
context = UIGraphicsGetCurrentContext();
//This is for flipping up sidedown
CGContextTranslateCTM(context, 0, self.imageViewArea.image.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// init vars
float d = 0; // squared error
int idx = 0; // index of palette color
int min = 1000000; // min difference
UIColor *oneRGB; // color at a pixel
UIColor *paletteRGB; // palette color
// visit each output color and determine closest color from palette
for(int y=0; y<sizeY; y++) {
for(int x=0; x<sizeX; x++) {
// desired (avg) color is one pixel of scaled image
oneRGB = [inputImgAvg colorAtPixel:CGPointMake(x,y)];
// find closest color match in palette: init idx with index
// of closest match; keep track of min to find idx
min = 1000000;
idx = 0;
CGContextDrawImage(context,CGRectMake(xx, yy, 1, 1),img);
}
}
UIImage *output = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imageViewArea.image = output;
This is a similar question (with no definitive answer), but the answer there has the code for directly accessing pixels from an image.
Quantize Image, Save List of Remaining Colors
You should do that rather than use CG functions for each get and set pixel. Drawing 1 pixel of an image onto another image is a lot slower than changing 3 bytes in a array.
Also, what's in ColorDiff -- you don't need perfect diffing as long as the closest pixel has the smallest diff. There may be room for pre-processing this list so that for each palette entry you have the smallest diff to the nearest other palette entry. Then, while looping through pixels, I can quickly check to see if the next pixel is within half that distance to the color just found (because photos tend to have common colors near each other).
If that's not a match, then while looping through the palette, if I am within half this distance to any entry, there is no need to check further.
Basically, this puts a zone around each palette entry where you know for sure that this one is the closest.
The usual answer is to use a k-d tree or some other Octree structure to reduce the number of computations and comparisons that have to be done at each pixel.
I've also had success with partitioning the color space into a regular grid and keeping a list of possible closest matches for each part of the grid. For example you can divide the (0-255) values of R,G,B by 16 and end up with a grid of (16,16,16) or 4096 elements altogether. Best case is that there's only one member of the list for a particular grid element and no need to traverse the list at all.

Extracting Dominant / Most Used Colors from an Image

I would like to extract the most used colors inside an image, or at least the primary tones
Could you recommend me how can I start with this task? or point me to a similar code? I have being looking for it but no success.
You can get very good results using an Octree Color Quantization algorithm. Other quantization algorithms can be found on Wikipedia.
I agree with the comments - a programming solution would definitely need more information. But till then, assuming you'll obtain the RGB values of each pixel in your image, you should consider the HSV colorspace where the Hue can be said to represent the "tone" of each pixel. You can then use a histogram to identify the most used tones in your image.
Well, I assume you can access to each pixel RGB color. There are two ways you can so depending on how you want it.
First you may simply create some of all pixel's R, G and B. Like this.
A pseudo code.
int Red = 0;
int Green = 0;
int Blue = 0;
foreach (Pixels as aPixel) {
Red += aPixel.getRed();
Green += aPixel.getGreen();
Blue += aPixel.getBlue();
}
Then see which is more.
This give you only the picture is more red, green or blue.
Another way will give you static of combined color too (like orange) by simply create histogram of each RGB combination.
A pseudo code.
Map ColorCounts = new();
foreach (Pixels as aPixel) {
const aRGB = aPixel.getRGB();
var aCount = ColorCounts.get(aRGB);
aCount++;
ColorCounts.put(aRGB, aCount);
}
Then see which one has more count.
You may also reduce the color-resolution as a regular RGB coloring will give you up to 6.7 million colors.
This can be done easily by given the RGB to ranges of color. For example, let say, RGB is 8 step not 256.
A pseudo code.
function Reduce(Color) {
return (Color/32)*32; // 32 is 256/8 as for 8 ranges.
}
function ReduceRGB(RGB) {
return new RGB(Reduce(RGB.getRed()),Reduce(RGB.getGreen() Reduce(RGB.getBlue()));
}
Map ColorCounts = new();
foreach (Pixels as aPixel) {
const aRGB = ReduceRGB(aPixel.getRGB());
var aCount = ColorCounts.get(aRGB);
aCount++;
ColorCounts.put(aRGB, aCount);
}
Then you can see which range have the most count.
I hope these technique makes sense to you.

Resources