alpha blending in gtk - graphics

How can you draw semi-transparent primitives such as filled polygons to a Drawable in GTK?
Its 2010, and I google isn't finding how to put an alpha value into a colour for me. What am I missing?

Use gtk.gdk.Drawable.cairo_create() and operate on the returned gtk.gdk.CairoContext. See documentation. Cairo is a generic vector 2D library that is used in GTK+ since many versions ago; GDK drawing primitives are deprecated in its favor (though not the whole GDK).

Here is actual source code to do it. I just wanted to gray out the entire pixbuf, but to do a shape you'd just have to use the appropriate path methods:
def getBlendedPixbuf(pixbuf, (r,g,b,a)):
"""Turn a pixbuf into a blended version of the pixbuf by drawing a
transparent alpha blend on it."""
pixbuf = pixbuf.copy()
#convert pixbuf to Drawable:
visual = gtk.gdk.visual_get_best()
screen = visual.get_screen()
cmap = screen.get_default_colormap()
w,h = pixbuf.get_width(), pixbuf.get_height()
drawable = gtk.gdk.Pixmap(
None, w, h, visual.depth)
gc = drawable.new_gc()
drawable.draw_pixbuf(
gc, pixbuf, 0,0,0,0,-1,-1)
#do all the drawing on it
cc = drawable.cairo_create()
cc.set_source_rgba(r,g,b,a)
cc.paint()
#put it back into a pixbhf
pixbuf.get_from_drawable(
drawable,cmap,0,0,0,0,w,h)
return pixbuf

Related

How to solve problem with transparent area in PNG image?

I use Paint.Net in Windows to make mask png image from source png.
def mask (im):
newimdata = []
transparent = (255, 255, 255, 0)
black = (0,0,0)
white = (255,255,255)
for color in im.getdata():
if color == transparent:
newimdata.append(white)
else:
newimdata.append(black)
newim = Image.new(im.mode,im.size)
newim.putdata(newimdata)
return newim
img = Image.open(thumb)
img = img.convert("RGBA")
mask(img).show()
The result is little weird.
Source png.
Mask png.
Left transparent rectangle I made in PaintNet: I clicked mouse, made transparent area.
Right transparent rectangle I made: I clicked mouse, made transparent area. After I clicked mouse once again and made transparent vertical figures on transparent rectangle.
I don't understand: Is it two transparent layers (right rectangle and vertical figures)?
How can I merge this to make mask as in left clean rectangle?
I don't understand what you are trying to do, but want to show you how the 4 channels (RGBA) of your image look. R is on the left, then G, then B with A (alpha/transparency) on the right.
I guess you just want the rightmost (A) channel, so with PIL, that is:
from PIL import Image
im = Image.open('....')
alpha = im.getchannel('A')
If you want all the channels, use:
R, G, B, A = im.split()

Merging overlapping transparent shapes in directx

This is the problem I am facing simplified:
Using directx I need to draw two(or more) exactly (in the same 2d plane) overlapping triangles. The triangles are semi transparent but the effect I want to release is that they clip to transparency of a single triangle. The picture below might depict the problem better.
Is there a way to do this?
I use this to get overlapping transparent triangles to not "accumulate". You need to create a blendstate and set it on output merge.
blendStateDescription.AlphaToCoverageEnable = false;
blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
blendStateDescription.RenderTarget[0].SourceBlend = D3D11.BlendOption.SourceAlpha;
blendStateDescription.RenderTarget[0].DestinationBlend = D3D11.BlendOption.One; //
blendStateDescription.RenderTarget[0].BlendOperation = D3D11.BlendOperation.Maximum;
blendStateDescription.RenderTarget[0].SourceAlphaBlend = D3D11.BlendOption.SourceAlpha; //Zero
blendStateDescription.RenderTarget[0].DestinationAlphaBlend = D3D11.BlendOption.DestinationAlpha;
blendStateDescription.RenderTarget[0].AlphaBlendOperation = D3D11.BlendOperation.Maximum;
blendStateDescription.RenderTarget[0].RenderTargetWriteMask = D3D11.ColorWriteMaskFlags.All;
Hope this helps. Code is in C# but it works the same in C++ etc. Basically, takes the alpha of both source and destination, compares and takes the max. Which will always be the same (as long as you use the same alpha on both triangles) otherwise it will render the one with the most alpha.
edit: I've added a sample of what the blending does in my project. The roads here overlap. Overlap Sample
My pixel shader is as:
I pass the UV co-ords in a float4.
xy = uv coords.
w is the alpha value.
Pixel shader code
float4 pixelColourBlend;
pixelColourBlend = primaryTexture.Sample(textureSamplerStandard, input.uv.xy, 0);
pixelColourBlend.w = input.uv.w;
clip(pixelColourBlend.w - 0.05f);
return pixelColourBlend;
Ignore my responses, couldn't edit them...grrrr.
Enabling the depth stencil prevents this problem

How to isolate a Phaser shader to a specific object/shape?

I'm using the Phaser framework. Here is the jsfiddle:
http://jsfiddle.net/Dillybob/u3mGL/13/
Here is where the filter is getting populated:
background = game.add.sprite(0, 0);
background.width = 800;
background.height = 600;
filter = game.add.filter('Fire', 800, 600);
filter.alpha = 0.0;
background.filters = [filter];
My line object is assigned to the variable drawnObject
So I assign that object to receive the filter like so:
drawnObject.filters = [filter];
But my line is now a red fiery square instead of being a line with a fiery background, why?
Firstly, be aware that drawnObject is actually a bitmap, which is rectangular shaped. It consists of white pixels, which build your line, and transparent pixels, which are taking the rest of bitmap space.
The filter you use is a pixel shader. Pixel shader describes instructions that GPU invokes for each pixel of a provided bitmap. In case of this shader, it creates fire effect based on some noise functions, but it doesn't take original bitmap into account. The original color of pixels is not preserved, it doesn't add to final effect in any way.
To achieve your expected result, you have to amend fragmentSrc in Fire.js, so that shader uses and mixes/blends original color into final pixel color and/or doesn't change pixel transparency.

Get pixel colors of tkinter canvas

I'd like to be able to create and interact with a Tkinter Canvas and, at any time, be able to iterate over each of its pixels and get their RGB values.
Setting pixel by pixel is not necessary, just getting. However, methods analogous to Canvas's create_polygon(), create_line(), create_text(), and create_oval() must be available as well for interacting with the image overall.
There are a number of restraints:
Must work with Python 3
Must work with Linux, Mac, and Windows
Must work with libraries that come with Python (no downloads)
The second restraint is mainly the reason I've posted this question when getting the color of pixels on the screen in Python3.x and several other similar questions already exist.
If this is impossible, what is the closest I can get?
Try it. But is slow :/
from util.color import Color
class ImageUtils:
#staticmethod
def get_pixels_of(canvas):
width = int(canvas["width"])
height = int(canvas["height"])
colors = []
for x in range(width):
column = []
for y in range(height):
column.append(ImageUtils.get_pixel_color(canvas, x, y))
colors.append(column)
return colors
#staticmethod
def get_pixel_color(canvas, x, y):
ids = canvas.find_overlapping(x, y, x, y)
if len(ids) > 0:
index = ids[-1]
color = canvas.itemcget(index, "fill")
color = color.upper()
if color != '':
return Color[color.upper()]
return "WHITE"
It's not possible. The canvas doesn't work that way.
If you're not interested in setting, you can use an image rather than a canvas. You can get the value of individual pixels in a PhotoImage.

HLSL beginner needs some directions

Is there any example out there of a HLSL written .fx file that splats a tiled texture with different tiles?Like this: http://messy-mind.net/blog/wp-content/uploads/2007/10/transitions.jpg you can see theres a different tile type in each square and there's a little blurring between them to make a smoother transition,but right now I just need to find a way to draw the tiles on a texture.I have a 2D array of integers,each integer equals a corresponding tile type(0 = grass,1 = stone,2 = sand).I opened up a few HLSL examples and they were really confusing.Everything is running fine on the C++ side,but HLSL is proving to be difficult.
You can use a technique called 'texture splatting'. It mixes several textures (color maps) using another texture which contains alpha values for each color map. The texture with alpha values is an equivalent of your 2D array. You can create a 3-channel RGB texture and use each channel for a different color map (in your case: R - grass, G - stone, B - sand). Every pixel of this texture tells us how to mix the color maps (for example R=0 means 'no grass', G=1 means 'full stone', B=0.5 means 'sand, half intensity').
Let's say you have four RGB textures: tex1 - grass, tex2 - stone, tex3 - sand, alpha - mixing texture. In your .fx file, you create a simple vertex shader which just calculates the position and passes the texture coordinate on. The whole thing is done in pixel shader, which should look like this:
float tiling_factor = 10; // number of texture's repetitions, you can also
// specify a seperate factor for each texture
float4 PS_TexSplatting(float2 tex_coord : TEXCOORD0)
{
float3 color = float3(0, 0, 0);
float3 mix = tex2D(alpha_sampler, tex_coord).rgb;
color += tex2D(tex1_sampler, tex_coord * tiling_factor).rgb * mix.r;
color += tex2D(tex2_sampler, tex_coord * tiling_factor).rgb * mix.g;
color += tex2D(tex3_sampler, tex_coord * tiling_factor).rgb * mix.b;
return float4(color, 1);
}
If your application supports multi-pass rendering you should use it.
You should use a multi-pass shader approach where you render the base object with the tiled stone texture in the first pass and on top render the decal passes with different shaders and different detail textures with seperate transparent alpha maps.
(Transparent map could also be stored in your detail texture, but keeping it seperate allows different tile-levels and more flexibility in reusing it.)
Additionally you can use different texture coordinate channels for each decal pass one so that you do not need to hardcode your tile level.
So for minimum you need two shaders, whereas Shader 2 is used as often as decals you need.
Shader to render tiled base texture
Shader to render one tiled detail texture using a seperate transparency map.
If you have multiple decals z-fighting can occur and you should offset your polygons a little. (Very similar to basic simple fur rendering.)
Else you need a single shader which takes multiple textures and lays them on top of the base tiled texture, this solution is less flexible, but you can use one texture for the mix between the textures (equals your 2D-array).

Resources