I'm trying to achieve the following:
Fill a textinput box in red or green depending on the value entered. It gets a little more complicated as the textinput is in a gallery and I only want it to go red or green if the selected question is 'FR Chlorine' or 'ph Actual'. The input box should be white if it is not one of those two questions.
To determine whether we want to fill in red or in green, there is another if statement which checks the value entered against predetermined variables which hold the comparison values. Can anyone help me to tidy this up as I seem to be in a bit of a pickle somewhere.
If(
ThisItem.question = "FR Chlorine",
If(
Value(txtResult.Text) < ChlorineLowerLevel,
Red,
Value(txtResult.Text) > ChlorineUpperLevel,
Red,
Green
),
White
);
If(
ThisItem.question = "ph Actual",
If(
Value(txtResult.Text) < phLowerLevel,
Red,
Value(txtResult.Text) > phUpperLevel,
Red,
Green
),
White
)
You can use something along the lines of the expression below:
If(
ThisItem.question = "FR Chlorine",
If(
Value(txtResult.Text) < ChlorineLowerLevel Or Value(txtResult.Text) > ChlorineUpperLevel,
Red,
Green
),
ThisItem.question = "ph Actual",
If(
Value(txtResult.Text) < phLowerLevel Or Value(txtResult.Text) > phUpperLevel,
Red,
Green
),
White
)
You could also do the same with the Switch function:
Switch(
ThisItem.question,
"FR Chlorine",
If(
Value(txtResult.Text) < ChlorineLowerLevel Or Value(txtResult.Text) > ChlorineUpperLevel,
Red,
Green
),
"ph Actual",
If(
Value(txtResult.Text) < phLowerLevel Or Value(txtResult.Text) > phUpperLevel,
Red,
Green
),
White
)
Related
I tried to render my surface with using alpha channel, but when I setting alpha value, it renders with random colors and not semi-transparent
// Init memory
Q3DSurface *poSurface = new Q3DSurface();
QSurface3DSeries *poSeries = new QSurface3DSeries();
QSurfaceDataArray *poDataArray = new QSurfaceDataArray();
// Generating test surface series
for ( int i = 0, k = 0; i < 10; ++i)
{
QSurfaceDataRow *poRow = new QSurfaceDataRow();
for ( int j = 0; j < 10; ++j )
{
float x = j;
float y = i;
float z = k;
poRow->append( QSurfaceDataItem( QVector3D( x, y, z ) ) );
}
poDataArray->append( poRow );
if ( i % 2 == 0 )
{
++k;
}
}
//
poSeries->dataProxy()->resetArray( poDataArray );
poSurface->addSeries( poSeries );
// Setting color with alpha value
poSeries->setBaseColor( QColor( 100, 100, 100, 100 ));
// Show surface widget
QWidget *poWidget = QWidget::createWindowContainer( poSurface );
poWidget->setWindowTitle( "test ");
poWidget->show();
What am I doing wrong?
I'm not sure what you mean by "random colours", but at a guess, are you accounting for the default lighting? The effect of the 3d lighting can make colours look differently to what they are explicitly set to.
With regard to your transparency setting, I think this code looks fine. You are setting the RGBA values as R=100, G=100, B=100, A=100 which will produce a grey colour. Under the default light this may look like light/dark patches because of the function you have graphed and the way the light "bounces" off the edges.
Try changing your code slightly to see if this is really what is happening:
poSeries->dataProxy()->resetArray( poDataArray );
poSurface->addSeries( poSeries );
//PICK A DARK THEME THAT WILL HELP TO ILLUSTRATE THE EFFECT
poSurface->activeTheme()->setType(Q3DTheme::ThemeEbony);
//TURN THE AMBIENT LIGHTING UP TO FULL
poSurface->activeTheme()->setAmbientLightStrength(1.0f);
// Setting color with alpha value
//SET IT TO RED WITH A FULL ALPHA CHANNEL
poSeries->setBaseColor( QColor( 100, 0, 0, 255 ));
// Show surface widget
QWidget *poWidget = QWidget::createWindowContainer( poSurface );
poWidget->setWindowTitle( "test ");
poWidget->show();
This should produce a dark red image of your graph with a dark background (just to make things clearer). Now put the alpha value back to what you wanted originally and you will see what effect this has on the colouring:
// Setting color with alpha value: "washed out" red colour
poSeries->setBaseColor( QColor( 100, 0, 0, 100 ));
You can probably see that it is the colour (rather than the mesh) that is being rendered at the transparency setting set through "setBaseColor".
Unfortunately I cannot tell you how to render transparently the Q3DSurface itself, but I hope that helps a little.
I'm trying to figure out how to make a Schindlers List (Movie) style photo filter for a .bmp file. For those who havent seen it, I want to be able to make everything grayscale except for red.
This is for a class and I am only allowed to use the following libraries : iostream, fstream, cstdlib, string, cstring.
The teacher was nice enough to give us the majority of the code, I just need to modify the pixels accordingly.
My grayscale algorithm isnt perfect. I got it by using fotor's grayscale filter and comparing the before and after RGB values. When I run this function the entire image ends up grayscale even though the picture has colors in the range I declared.
If someone could help me make this work thatd be great!
void process( int& red, int& green, int& blue ) //schindler's list filter
{
if( red < 143 && red > 80 &&
green < 64 && green > 24 &&
blue < 70 && blue >> 30 )//my red range
{
red = red;
blue = blue;
green = green;
}
else //if the pixel isnt red the program will go ahead and make it grayscale
{
red = ((red + green) / 2)*1.01;
green = red;
blue = red;
}
}
blue >> 30
Silly typo: you meant blue > 30.
blue >> 30 is basically always zero, which converts to false which leaves your "leave the colours as they are" block unreachable.
If someone could help me make this work thatd be great!
We're not really here for that. Next time please do some debugging.
Remove conditions, output the values of expressions and variables, until you find the one that isn't what you expect. Make a testcase. Abstract away your specific use case (i.e. the name of a film is not relevant to the problem).
BTW, as a matter of style, red = red etc is utterly pointless!
As a commentator said, in a classic RGB colorspace, a greyscale value is computed with the formula
grey = .2126*red + .7152*green + .0722*blue;
Also, if you just make a brutal transition between the colors you want to preserve and the grey areas, it might look like the colored zones have been painted over the picture.
I would rather apply a smoothing based on the color you want to make stand out.
// this is the center of the intervals you defined for your color
#define TARGET_R 111
#define TARGET_G 44
#define TARGET_B 50
// color distance to consider to mix grey and pure color
#define RADIUS 20 // R, G or B component
int dr = red - TARGET_R;
int dg = green - TARGET_G;
int db = blue - TARGET_B;
int dist = sqrt(dr*dr+dg*dg+db*db); // distance from target color
int grey = .2126*red+.7152*green+.0722*blue; // grey color
float color; // fraction of pure color
if (dist > RADIUS) // pure grey beyond radius
color = 0;
else if (dist > RADIUS/2) // slope from 0 # radius to 1 # radius/2
color = (RADIUS-dist)*2.0/RADIUS;
else // pure color between 0 and radius/2;
color = 1;
grey *= (1-color); // grey part
red = red * color + grey;
green = green * color + grey;
blue = blue * color + grey;
Another approach you could take is to convert the RGB color to HSV (Hue Saturation Value) color space, and than bring the saturation down only if the hue is not in a specific range. For example:
if( 30 < h && h < 330 ) s = 0
http://en.wikipedia.org/wiki/HSL_and_HSV
I've written code in Arduino that cycles through 3 LED color lights but it seems (code) bug prone so I'm trying to come up with a new way to write it. Due to the complexity I'm going to stick with the phesdo code of what I'm trying to do. Here it is:
If (red LED isn't max and green LED is 0 and blue LED is 0)
{inc red LED; update dot matrix}
If (red LED is max and green LED isn't max and blue LED is 0)
{inc green LED; update dot matrix}
If ((red LED is/has-been max but not 0 ) and green LED is max and blue LED is 0)
{dec red; update dot matrix}
If (red LED is 0 and green LED is max and blue LED isn't max)
{inc blue; update dot matrix}
If (red LED is 0 and (green LED is/has-been max but not 0) and blue LED is max)
{dec green; update dot matrix}
If (red LED isn't Max and green LED is 0 and blue is Max )
{inc red; update dot matrix}
If (red LED is Max and green LED is 0 and (blue LED is/has-been Max but not 0))
{dec blue; update dot matrix}
Update LED Driver;
Note: For a visual it's a color wheel going red->orange->green->teal->blue->pink->repeat
The caveat is, all this is in a loop that is only run once before exiting to fetch other data. It then has to return to this loop and remember the color location it left off. Other wise it would be very easy to wrap all this in for loops and execute it linearly. As it is it has to inc or dec one color, understand it's color position if you will, update the led driver and then come back to inc or dec remembering where it left off. So does anyone have a better code methodologically, pseudo style, I can use besides this complex if statements style.
With a simple drawing of the situation you are able to find a formula that applies the intensity directly to the single component according to a global counter that you increment on every tick, the code is the following (I wrote it just now and haven't tested but should be enough for you to understand how it works):
int counter = 0; // counter you should increment on each tick
int phases = 6; // total phases in a cycles
int cycleLength = max_steps * phases; // total ticks in a cycle
int currentStepOfCycle = counter % cycleLength;
int currentPhase = currentStepOfCycle / max_steps;
int currentStepOfPhase = currentStepOfCycle % max_steps;
// this is how much phase shifts are performed for each primary color to have the raising line in phase 0
int phase_shifts[3] = {2, 0, 4};
// for each color component
for (int i = 0; i < 3; ++i) {
// shift the phase so that you have / at phase 0
int shiftedPhase = (currentPhase+phase_shifts[i])%phases;
if (shiftedPhase == 1 || shiftedPhase == 2)
intensity[i] = MAX;
else if (shiftedPhase == 0)
intensity[i] = currentStepOfPhase;
else if (shiftedPhase == 3)
intensity[i] = MAX - currentStepOfPhase;
else
intensity[i] = 0;
}
The idea follows from this:
The shift is needed because by adding an increment to the current phase for a different color component it is possible to consider always phase 0, 1, 2 and 3 to understand is intensity should be raising, dropping or set to max for each component.
This should be adaptable to whatever step of intensity you want to apply easily.
At least as I read your if statements, you have 7 distinct states (maybe it should be 8?), and when you reach the last, it wraps back around to the first.
That's pretty easy to implement as a counter with a small lookup table to map from a state number to which LED(s) should be lit for a state.
yeah that is not great... I would do something like..
typedef struct{ //maybe stick this in a union, depending on what the compiler does to it.
unsigned char r:2;
unsigned char g:2;
unsigned char b:2;
}color;
const int numOfColors = 3;
color colors[numOfColors] = {
{2,0,0},//r
{1,1,0},//o
{0,2,0}//g
};
for(int i = 0 ; 1 ; i++)
{
color c = colors[i%numOfColors];
//set color
//update
//wait
}
The following image of size 1x9 is being trimmed to 1x6 because presumably the pixel at the top is the same color as the pixel at the bottom and in the trim function, these pixels are being identified as the background color, even though the backgroundColor being reported before the execution of the trim function is #FFFFFF.
http://s1.postimage.org/a7r69yxsr/m_medium_bc.png
The only thing I am doing is executing trim on the Image. Explicitly setting backgroundColor and/or transparent() makes no difference.
Why is this occurring and is this the expected behavior?
Can this be fixed by configuration/property setting/without changing Graphicsk library code?
If not, when can this bug be fixed? Do you expect a bug of this nature to be fixed in the next few days?
Here is the code:
Magick::Image tempImage;
tempImage.read(name);
std::cout<<"size:"<<tempImage.columns()<<","<<tempImage.rows()<<std::endl;
temp=tempImage.backgroundColor();
std::cout<<"bg:"<<(std::string)temp<<std::endl;
tempImage.trim();
std::cout<<"size:"<<tempImage.columns()<<","<<tempImage.rows()<<std::endl;
I agree that this behaviour is strange, I am not a developer/maintainer of ImageMagick/Magick++ so can't comment further as to whether this is a bug or 'feature'. However I had the same issue and created this function as a workaround (note this is much faster than manually iterating the pixels, even with a pixel cache in place):
Magick::Geometry CalculateImageMagickBoundingBox( const Magick::Image & image, const Magick::Color & borderColor )
{
// Clone input image.
Magick::Image clone( image );
// Remember original image size.
const Magick::Geometry originalSize( image.columns( ), image.rows( ) );
// Extend geometry by two in width and height (one pixel border).
Magick::Geometry extendedSize( originalSize.width( ) + 2, originalSize.height( ) + 2 );
// Extend cloned canvas (center gravity so 1 pixel border of user specified colour).
clone.extent( extendedSize, borderColor, Magick::CenterGravity );
// Calculate bounding box (will use border colour, which we have set above).
Magick::Geometry boundingBox = clone.boundingBox( );
// We added 1 pixel border, so subtract this now.
boundingBox.xOff( boundingBox.xOff( ) - 1 );
boundingBox.yOff( boundingBox.yOff( ) - 1 );
// Clamp (required for cases where entire image is border colour, and therefore the right/top borders
// that we added are taken into account).
boundingBox.width( std::min( boundingBox.width( ), originalSize.width( ) ) );
boundingBox.height( std::min( boundingBox.height( ), originalSize.height( ) ) );
// Return bounding box.
return boundingBox;
}
In your particular case, you could use this function and then set the canvas size based on the geometry returned.
I need to create a colorbar like THIS
I use a scaled array of floats between 0 and 1.
Now I want to compute the RGB color from this float. How to do it? Want to write it in C/c++ so I think I need 2 functions.
The first function to build the colorbar with one parameter like STEPSIZE and the second function need the value and must just return the array index of the colorbar.
I couldn't find it on google, so please help me.
What you are referring to here is the 100% EBU Color Bars (named after the standards body, the European Broadcasting Union). This is not the same as the full SMPTE RP 219-2002 color bars, which have other features including gradients and the PLUGE (Picture Line-Up Generation Equipment), described in the Wikipedia article on Color Bars.
The EBU Color Bars consist of 8 vertical bars of equal width. They are defined in the same way for both SD and HD formats. In the RGB color space, they alternate each of the red, green and blue channels at different rates (much like counting in binary) from 0 to 100% intensity. Counting down from white, in normalised RGB form (appearing left to right):
1, 1, 1: White
1, 1, 0: Yellow
0, 1, 1: Cyan
0, 1, 0: Green
1, 0, 1: Magenta
1, 0, 0: Red
0, 0, 1: Blue
0, 0, 0: Black
So the blue channel alternates every column, the red channel after two columns, and the green after four columns. This arrangement has the useful property that the luminance (Y in YCb'Cr' colour space) results in a downward stepping plot.
To render using 8-bit RGB (most commonly found in desktop systems), simply multiply the above values by 255. The EBU bars come in 75% and 100% variants, based on the intensity of the white column. The SMPTE color bars typically use 75% levels as a reference.
Here is some simple C code to generate 100% EBU color bars and save the result as a PGM file:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// PAL dimensions
static const unsigned kWidth = 720;
static const unsigned kHeight = 576;
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
} RGB;
int main(int argc, char* argv[])
{
const RGB BAR_COLOUR[8] =
{
{ 255, 255, 255 }, // 100% White
{ 255, 255, 0 }, // Yellow
{ 0, 255, 255 }, // Cyan
{ 0, 255, 0 }, // Green
{ 255, 0, 255 }, // Magenta
{ 255, 0, 0 }, // Red
{ 0, 0, 255 }, // Blue
{ 0, 0, 0 }, // Black
};
// Allocate frame buffer
size_t frameBytes = kWidth*kHeight*sizeof(RGB);
RGB* frame = malloc(frameBytes);
unsigned columnWidth = kWidth / 8;
// Generate complete frame
for (unsigned y = 0; y < kHeight; y++)
{
for (unsigned x = 0; x < kWidth; x++)
{
unsigned col_idx = x / columnWidth;
frame[y*kWidth+x] = BAR_COLOUR[col_idx];
}
}
// Save as PPM
FILE* fout = fopen("ebu_bars.ppm", "wb");
fprintf(fout, "P6\n%u %u\n255\n", kWidth, kHeight);
fwrite(frame, frameBytes, 1, fout);
fclose(fout);
free(frame);
return 0;
}
This should be readily adaptable to any other language. There's probably no need for using float unless you're implementing this on a GPU (in which case the algorithm would be quite different). There is much scope for optimization here; the code is written for clarity, not speed.
Note that while it is possible to generate a perfect digital representation of the color bars in a computer, this will not be safe for broadcast. The transitions between "perfect" color bars would require infinitely high bandwidth to accurately represent. So if the test image is to be transmitted via analog broadcast equipment, it must be bandwidth-limited by a low-pass filter (eg. ~4.3MHz for PAL). This is why you notice the "fuzzy" boundaries in between each column; these contain intermediate values between the pure colors.
Also note that it is not possible to accurately represent the SMPTE color bars in the RGB color space. This is because certain critical values are specified in the YCb'Cr' color space (notably in the PLUGE region) which are outside the gamut of RGB (either SD or HD). You can create something that approximates the values (eg. a very dark blue) but they are not correct. So unless you are representing the test frame in YCb'Cr', stick to EBU bars only (the upper 2/3).
RGB uses bytes, so assuming your array of floats is something like
float scaledColor[3]; // 0 = R, etc., all 0.0 < scaledColor[x] < 1.0
then you can do:
unsigned char r = (unsigned char)(255 * scaledColor[0]);
unsigned char g = (unsigned char)(255 * scaledColor[1]);
unsigned char b = (unsigned char)(255 * scaledColor[2]);
This will of course only work if the values in the floats are really in the range from 0.0 to 1.0.
The simplest solution:
const unsigned char* getColour(float x) /* 0 <= x < 1 */
{
static const unsigned char bar[][3] = {
{255,255,255},
{255,255,0},
// ... fill in all the colours ...
{0,0,0}
};
return bar[(int)(x*sizeof(bar))];
}
Then you can use it to generate bars of any width.
My google-fu turned up that you want the upper third of a SMPTE color bar pattern.
Wikipedia says:
In order from left to right, the colors are gray, yellow, cyan, green,
magenta, red, and blue.
So the easiest way is to simply hard code the respective RGB color codes if you only need those. The article also mentions how those colors can be generated but this seems a lot more difficult and isn't really worth the effort for seven colors.