Anti-Aliasing Images in a panel - python

I'm setting the shape of a wxPanel, but there are a lot of jagged edges. Is there a way to smooth these out?
Inside of the wx.Frame, I am setting the shape from a black and white .png image
mask = wx.Image('Resources/Images/Window/window_alpha_map.png')
mask.ConvertAlphaToMask()
shape = mask.ConvertToBitmap()
shape.SetMask(wx.Mask(shape, wx.BLACK))
self.SetShape(wx.RegionFromBitmap(shape))
Inside of the wxPanel, I am then setting the image in eraseBackground
def onEraseBackground(self, event):
dc = event.GetDC()
if not dc:
dc = wx.ClientDC(self)
rect = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rect)
dc.Clear()
background = wx.Image('Resources/Images/Window/window_background.png')
bmp = background.ConvertToBitmap()
dc.DrawBitmap(bmp, 0, 0)
Here are some examples of what I am talking about: http://clfu.se/PZn3 http://clfu.se/uE4
Is there a way to smooth these out in wxPython or even a trick in photoshop I am missing?
Any help is appreciated

You would probably be better off to just draw the image using a GraphicsContext widget as that supports anti-aliasing:
http://wxpython.org/Phoenix/docs/html/GraphicsContext.html
wxPython also allows drawing via Cairo, which also support anti-aliasing:
http://wiki.wxpython.org/UsingCairoWithWxPython
Finally, you could also take a look at FloatCanvas:
Best canvas for drawing in wxPython?

Related

Overwriting a border on an image in Python PIL

I have a gallery application where the users upload photos and my code gives it a border, writes some of the photo attributes on the border and stores it.
image2 = Image.open('media/' + str(image.file))
width, height = image2.size;
image2 = ImageOps.expand(image2, border=(int(width/25),int(height/20),int(width/25),int(height/10)), fill='rgb(0,0,0)')
(Note that here my bottom border is longer than the top because I am writing attributes on the bottom border.)
Now I'm building an edit feature for the uploaded images where the user can change the attributes of the uploaded images. But the attributes that are already written on the border have to be overwritten.
So here, my approach is to put a black patch on the bottom border and re-write the new attributes without changes the top and side borders and without changing the aspect ratio. All of this has to be done using PIL.
Question is how do I put a black box on the bottom border?
I tried ImageOps.fit() as mentioned here https://pillow.readthedocs.io/en/3.3.x/reference/ImageOps.html#PIL.ImageOps.fit, but the aspect ratio doesn't seem to be right and I want to overwrite on the black border a black box and not crop the photo.
To me it seems like the easiest solution is just quickly draw the black pixels in the area that you want using a couple loops and Image.putpixel
from PIL import Image
img = Image.open('red.png')
for x in range(img.width):
for y in range(img.height - 40, img.height):
img.putpixel((x, y), (0, 0, 0))
img.save('red2.png')
The simplest way in my opinion is to create a new black image and paste onto your existing image -
from PIL import Image
im = Image.open('test.png')
blackBox = Image.new(im.mode, (im.width, 50), '#000')
im.paste(blackBox, (0, im.height - blackBox.height))
Alternatively, you could use ImageDraw - http://pillow.readthedocs.io/en/5.2.x/reference/ImageDraw.html - which you could use to draw rectangles and other shapes.
from PIL import Image, ImageDraw
im = Image.open('test.png')
d = ImageDraw.Draw(im)
d.rectangle((0, im.height - 50, im.width, im.height), fill='#000')

HTML5 canvas source-atop alternative in PIL

I cannot find the right function to add color overlay on another image when transparent areas should remain untouched.
For example on source image there is a semi-transparent white circle and around it everything is fully transparent. When I apply the operation with red color, I'd like to get white/red circle with fully transparent area around it.
On HTML5 canvas, it is achieved by:
layerContext.globalCompositeOperation = "source-atop";
layerContext.fillStyle = color;
layerContext.fillRect(0, 0, w, h);
I tried alpha_composite, blend and composite functions, but maybe misused them.
EDIT: here is what I get using:
overlay = Image.new('RGB', im1.size, (255, 0, 0))
im1.paste(overlay, mask=im1)
Canvas:
PIL:
PIL result is a little bit lighter, but color is the same. Any ideas?

Kivy Interpolation on Canvas

I am new to kivy and python. I am trying to have an texture (256x256) shown pixelated through my canvas, but it is blurred, and through some googling i think it is interpolated? I want it to show the pixels with sharp edging and not blurred. It also blends in color from surrounding tiles in the texture when i use texture.get_region(...) to select one tile (64x64) and display that, so i get a border from the other tiles in my new texture. I guess i am just really bad at reading Kivy's documentation.
texture = Image('template.png').texture //getting texture
topright = texture.get_region(64, 64, 64, 64) //Selecting a specific Tile
with self.canvas:
Rectangle(texture = texture, pos = self.pos, size = (512,512))
Set
texture.mag_filter = 'nearest'
texture.min_filter = 'nearest'
You might only need one of these, I don't remember, but you can test and see the doc at http://kivy.org/docs/api-kivy.graphics.texture.html

PIL selection of coordinates to make an image

I am wanting to create an image from a selection of coordinates i have. So I want each coordinate to be set a particular size and colour say black and 2X2, and then place it at the particular pixel it represents.
How will i go about this?
Will the function putpixel, work for what I want to do?
Thanks in advance
Doing this with putpixel will be inconvenient but not impossible. Since you say you want to make dots of more than a single pixel, it would be better to use ImageDraw.rectangle() or ellipse() instead.
For example:
import Image
import ImageDraw
img = Image.new("RGB", (400,400), "white")
draw = ImageDraw.Draw(img)
coords = [(100,70), (220, 310), (200,200)]
dotSize = 2
for (x,y) in coords:
draw.rectangle([x,y,x+dotSize-1,y+dotSize-1], fill="black")
img.show()

Why glDrawpixels does not render my transparent background?

I want to render font in opengl with transparent background.
The main problem is that my background is always opaque black !
here is my code :
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
font = ImageFont.truetype("/usr/share/fonts/truetype/wqy/wqy-microhei.ttc", 16)
textsize = font.getsize(u"当前运行列表")
im = Image.new("RGB",textsize,"#000")
draw = ImageDraw.Draw(im)
transparent_area = (0,0,im.size[0],im.size[1])
mask=Image.new('L', im.size, color=0)
drawmask = ImageDraw.Draw(mask)
drawmask.rectangle(transparent_area, fill=0)
im.putalpha(mask)
draw.text((0,0), u"当前运行列表", font=font, fill="red")
#im.save('render.png')
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1)
glDrawPixels(ix,iy,GL_RGBA,GL_UNSIGNED_BYTE,image)
Cheers, it is not fully clear what are you trying to acheive. You could either be trying to have a transparent font rendered over some other OpenGL geometry, or maybe you want to render contents of the window using OpenGL and make parts of the window transparent (so you can see windows behind it).
To make window transparent, you need to use:
// Set WS_EX_LAYERED on this window
SetWindowLong(hwnd,
GWL_EXSTYLE,
GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Make this window transparent
int transparentColor = RGB(x, y, z);
SetLayeredWindowAttributes(hwnd, transparentColor, 255, LWA_COLORKEY);
This enables so called color keying on the window, that means anything that is rendered using RGB(x, y, z) gets transparent, and the window is not visible in these parts. Note that this transparency is binary, it is either fully transparent or fully opaque. Also, you need to be using GDI to render to your window. That means either do not use OpenGL at all, and use function like BitBlt() or StretchBlt() instead, or use OpenGL to render into a P-buffer (or into a FBO, framebuffer object), then use glReadPixels() to copy the output, and then use BitBlt() again to display the results using GDI. In your case where you are trying to render a piece of text, you might be better off without using OpenGL.
So, in your example you could make black color transparent, i.e. x = y = z = 0, do not use OpenGL, and create a device independent bitmap (DIB) instead using CreateDIBSection(), fill it with image instead of passing it to glDrawPixels() and render to window using BitBlt().
added this at beginning
glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE )
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE )
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 )
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 )
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 )
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 )

Categories