Separating image into RGB channels and reconstructing original by stacking? - css

Is it possible to separate a photo's RGB channels in a way that if you stack the separate images on top of each other (say in an HTML page with the images being a transparent "channel" stacked on top of each other), you can see the original image the way it was?
I tried grabbing a selection from each channel and making making it a separate layer in that channel's color, but it seems like I'm missing something, or the way channels work is more complicated than I think.
The reason I ask is because if I could get this to work, then I could manipulate the opacity of each color separately using CSS and get some neat effects (without using canvas).

I've answered my own uncertainty on this:
This process cannot recreate the original image.
(Which is what JamWaffles said in short in his comment.) Here's the explanation why:
You can take a photo and split out the RGB channels from software like Photoshop.
You can manipulate those gray scale channels in such a way to add have various alpha levels of Red, Green, and Blue and save that into a .png. So far, so good.
You cannot recombine them correctly by layering in css. Assume you have some area of the photo that is white. Note the following:
Alpha Channel Combining (is additive)
Red Layer (255, 0, 0) + Green Layer (0, 255, 0) + Blue Layer (0, 0, 255) = You see RGB(255, 255, 255), i.e. white.
CSS Layer Combining (is not additive; it will cover lower layers)
Red (top) Layer (255, 0, 0) + Green (middle) Layer (0, 255, 0) + Blue (bottom) Layer (0, 0, 255) = You see RGB(255, 0, 0), i.e. only the top layer, which is red, as it covers the green and blue layers at the point where it is 100% opaque.
So until such a time as css may offer an option to have layers "add" to one another rather than "cover" one another, then such an idea is not possible. Now that is not to say you could not achieve some rather interesting effects with layered .pngimages with monochromatic colors, and later manipulating opacity of the layers further through css, you just cannot ever recreate the image through the stacking of the channels in css.

According to this specification: http://dev.w3.org/fxtf/compositing-1/#mix-blend-mode
CSS can support color blending, it just isn't implemented on most browsers. However many
browsers support the use of color blending in the '2d' canvas context. This blog post
demonstrates the use of canvas for color blending animations and an very basic explanation of the idea. http://mackenziestarr.co.nf/blog/?p=7

Related

How does transparency in rgba work?

I have recently learned about rgba for setting colours in css. I am curious about the technical aspect of the transparency channel actually works.
For example, if I set the values to be rgba(15, 34, 160, 1) and rgba(15 34, 160, 0.5) for two separate headers, then they are referred to as having the same colour, but having a different opacity value. What I am wondering is whether or not these colours are actually the same. By this I mean that in terms of the light coming out the pixels, they must surely be different in order to create two different looks of headers. Does this mean that the alpha value is actually used to change the colour in some sort of specific way?
Cheers!
since you can "half see" the color of the element behind a half-transparent element, it will be mixed with that color (if the background is white, it will appear lighter, if it's black, darker, and if it's another color there will also be a mixture of the colors.
So, technically it's the same color with different transparency, but the perceived result will be a different color (unless by chance the element behind the transparent one has the same color)
An RGB value is a color, an RGBA value is a color plus transparency. When you overlay it on a colored background, it can result in a different apparent color. So yes, they are the same COLOR, but can result in different colors depending on where they are.
Check out this JSFiddle
Play with the the top CSS property that looks like this:
background-color: rgba(225, 225, 225, 0.7);
The last value there is the opacity (opposite of transparency) measured from 0 to 1. 0 is fully transparent and 1 is fully opaque. The first three values are just like a regular rgb() CSS property.
By setting an RGBA color value. You are really just setting the color and a separate opacity value. This could be accomplished by setting the color with RGB and then the opacity separately with opacity, but RGBA combines the two into a single function. Using RGBA is shorter, but setting RGBA and then opacity separately allows you control over the values separately.
So, your two examples are setting the same value for color, but applying two different levels of opacity to that color.

Gradient created in a style sheet look different from those created via a QBrush?

I am using Qt 4.8.5 with a tree view and I would like to color the background of some items with a gradient depending on what the user is doing. One possibility is that the user moves the mouse over a tree item. The only way to set the background to a gradient in this case is to define a style sheet like that and to set it as the tree views style sheet:
QTreeView::item:hover { background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 rgb(255, 255, 255), stop: 1 rgb (0, 255, 255);
border: 1px solid rgb (0, 255, 255); }
This works.
There are situations where I would like to mark tree items the same way, even when the mouse is not placed over this tree item (there is a 3D view and some items of the 3D view correspondent to tree items – I would like to highlight the tree view items, when the user points on those items in the 3D view).
This is also possible. I the data(…) method of the document tree model, I return a brush that I have created like this:
QLinearGradient gradient(0, 0, 0, 1);
gradient.setColorAt(0, QColor(255, 255, 255));
gradient.setColorAt(1, QColor(0, 255, 255));
QBrush brush(gradient);
This also works. The only problem is, that the gradient defined with the brush is much different from the gradient defined with the style sheet, even though the numbers are the same (actually in this example the complete background is white – but when I play with the numbers I realize that it is indeed a gradient, but not the one I had expected).
Could someone explain me the reason?
I thought that this could be the case because the QLinearGradient interprets the x1, x2, y1, y2 value as pixels. Does the style sheet interpret these values as relative values? I have played around with the coordinate mode of the gradient, but this did not help.
How can I make both gradients look the same? Or should I get rid of those style sheets and define everything with QBrush’s?
Another question: my impression is, that those Qt style-sheets are not really well-thought-out. Is this just because I don't know yet how to use them or is this really the case?
I will try to make the problem clearer by adding some screen shots (I should have done that immediately). The coordinate mode of the following QLinearGradient instances has been set to QGradient::ObjectBoundingMode:
This is the tree item with the gradient defined by the style sheet:
This is the tree item with the gradient defined by the QBrush with a QLinearGradient(0, 0, 0, 1):
This is the tree item with the gradient defined by the QBrush with a QLinearGradient(0, 0, 1, 1):
My problem is: neither of the QBrush/QLinearGradient combinations looks like the gradient defined by the style sheet. Is anyone out there who has managed to create a QBrush/QLinearGradient that looks like the style sheet gradient?
Sadly, you can NOT change the CoordinateMode of your gradient in Qt CSS qlineargradient(...).
It is always QGradient::ObjectBoundingMode, see the code.
You can change the CoordinateMode of your gradient. Set it to QGradient::ObjectBoundingMode if you want it to be relative to the bounding rectangle, like it is in the stylesheets.
From the stylesheet reference docs: Gradients are specified in Object Bounding Mode.
One thing that is wrong in your code, is the usage of QGradient::setColorAt. You are using 255 as the position parameter, even though the acceptable range is between 0 and 1. You should be receiving a warning message for this.
The QGradient::ObjectBoundingMode option does not work as expected for item view items. I was able to accomplish a similar task in a QTableView by using the default mode and pixel coordinates. The coordinates are relative to the item's visual rectangle. In my case, I have access to the view and was able to use QAbstractItemView::visualRect().
if (role == Qt::BackgroundRole)
{
QColor c = ...
QRectF r = table()->visualRect(mi);
QLinearGradient g(0,0, 0,r.height());
g.setColorAt(0, c.lighter(200));
g.setColorAt(1, c);
return QBrush(g);
}

Should you use rgba(0, 0, 0, 0) or rgba(255, 255, 255, 0) for transparency in CSS?

Should you use rgba(0, 0, 0, 0) or rgba(255, 255, 255, 0) for transparency in CSS?
What are the pros and cons of each?
The last parameter to the rgba() function is the "alpha" or "opacity" parameter. If you set it to 0 it will mean "completely transparent", and the first three parameters (the red, green, and blue channels) won't matter because you won't be able to see the color anyway.
With that in mind, I would choose rgba(0, 0, 0, 0) because:
it's less typing,
it keeps a few extra bytes out of your CSS file, and
you will see an obvious problem if the alpha value changes to something undesirable.
You could avoid the rgba model altogether and use the transparent keyword instead, which according to w3.org, is equivalent to "transparent black" and should compute to rgba(0, 0, 0, 0). For example:
h1 {
background-color: transparent;
}
This saves you yet another couple bytes while your intentions of using transparency are obvious (in case one is unfamiliar with RGBA).
As of CSS3, you can use the transparent keyword for any CSS property that accepts a color.
There are two ways of storing a color with alpha. The first is exactly as you see it, with each component as-is. The second is to use pre-multiplied alpha, where the color values are multiplied by the alpha after converting it to the range 0.0-1.0; this is done to make compositing easier. Ordinarily you shouldn't notice or care which way is implemented by any particular engine, but there are corner cases where you might, for example if you tried to increase the opacity of the color. If you use rgba(0, 0, 0, 0) you are less likely to to see a difference between the two approaches.
There a small difference when u use rgba(255,255,255,a),background color becomes more and more lighter as the value of 'a' increase from 0.0 to 1.0. Where as when use rgba(0,0,0,a), the background color becomes more and more darker as the value of 'a' increases from 0.0 to 1.0.
Having said that, its clear that both (255,255,255,0) and (0,0,0,0) make background
transparent.
(255,255,255,1) would make the background completely white where as (0,0,0,1) would make background completely black.
I would recommend using rgba(255,255,255,0) because broken (newest) safari thinks that if you are using transparent or rgba(0,0,0,0) in linear-gradent you really mean gray, For more info please head to - What happens in Safari with the transparent color?

How do you create a texture effect with css?

You can see it done here http://qunitjs.com/ and broken down here http://jsfiddle.net/xMwT8/8/ *edit (http://jsfiddle.net/xMwT8/9/)
links are available
here
here
here
here
I am trying to use an image as a texture with an overlay color above or combined with the image to blend into a subtle texture. It can be done with a gradient (like in the first and second link I posted). I don't understand why it won't work with just a color (2nd link).
I think you are asking why you can't do this with a solid color like #E4E2D6. The simple explanation is that it's a solid color :)
the jsfiddle example uses rgba(255, 0, 0, 0.3) which isn't a solid color, it's a 70% transparent red (the a == 0.3 means it's only 30% opacity)
If you want to do it with something like #E4E2D6, take a look at Convert RGB to RGBA over white and convert it to rgba(87, 74, 0, 0.16) which is the same color (when displayed over white, but it's mostly transparent) and will allow the background through.
Okay, just looked at the /9 fiddle (FYI you can just change the original link instead of putting an edit like that). It seems that this doesn't work with
background: rgba( ... ), url( ... );
Why? Because you can only have multiple background images. The -webkit-linear-gradient is an image as far as the browser is concerned, so it uses both. rgba( ... ) without it is a color, so it uses the image and the color as a fallback

Why does the file size of a png24-sprite increase when adding transparent white-space?

I am creating a png24 as sprite for css background images.
Due to padding issues I have to keep a certain amount of space between the icons in the sprite.
When doing so the file size of the png increases even though no information was added... Just empty, transparent space.
Is there any workaround for this? (I have already tried png compression - smushit - but no significant improvement made...)
Thanks
Empty, transparent space is information as well. If a PNG has an alpha channel, then every pixel consists of the informations (r,g,b,a) for red, green, blue and alpha components. In case of a transparent pixel the alpha is simply 0, but it's nevertheless information that is present in the file.
Empty is still kind of data, so when you add an empty space, you add a data that tells the PNG decoder about the empty space between each graphic.
I suppose the added file size is insignificant next to making extra requests to the server.

Resources