I have 2 images:
PNG (99x97) with white, rotated frame and rest is in full transparency.
JPG - is my generated thumbnail (80x80)
Now I want to put thumbnail into my frame so it looks like some kind of painting. What should I do?
EDIT:
I forgot to add, that picture must be under the frame.
Frame image
I have some script but it shows only a frame. There is no picture in it :/
import Image, ImageDraw
img_size = (99,97)
im = Image.open('logo.jpg')
picture = im.crop((0,0,80,80))
frame = Image.open('thumb-frame.png')
picture = picture.convert('RGBA')
background = Image.new('RGBA', img_size, (255, 255, 255, 0))
background.paste(picture, (10,9))
background.paste(frame, (0,0))
background.save('logocopy.png', 'PNG')
EDIT:
Problem solved. I had to add alpha mask to .paste()
import Image
im = Image.open('logo.jpg')
picture = im.crop((0,0,80,80))
picture = picture.convert('RGBA')
frame = Image.open('thumb-frame.png')
background = Image.new('RGBA', frame.size, (255, 255, 255, 0))
background.paste(picture, (10,9))
background.paste(frame, (0,0), frame)
background.save('logocopy.png', 'PNG')
Here you go. This should take original picture and paste transparent frame image above it. Both pictures should be 100x100, but you can add needed resizing.
from PIL import Image
frame = Image.open('frame.png')
img = Image.open('image.jpg')
img_dest = img.copy().convert('RGBA')
img_dest.paste(frame, (0, 0, 100, 100), frame)
img_dest = img_dest.convert('RGB') # Optional, to remove transparency info
img_dest.save('output.png')
Related
Here is an example of the output I want to generate. I'm able to create an image with one color, but I don't have idea of how can use two colors, and how to color only certain parts of the image .
I solved in this way. I created two image with two different colors, and then paste them in another one image.
width = 400
height = 300
img = Image.new( mode = "RGB", size = (width, height), color = (209, 123, 193) )
#First IMG
img2 = Image.new( mode = "RGB", size = (width, height + 400), color = (255, 255, 255) )
#Second IMG
img3 = Image.new('RGB', (img.width, img.height + img2.height)) img3.paste(img, (0, 0)) img3.paste(img2, (img.width, 0))
#IMG + IMG2
I got my result.
Suppose you have .tif file which has 14 pages (multi image tif). I'd like to draw a rectangle on a specific place on a specific page. However, below example does not paste my img which I drew with ImageDraw anywhere on the second page. Where am I failing this?
from PIL import Image, ImageDraw
im = Image.open('tiffile.tif')
for i, page in enumerate(ImageSequence.Iterator(im)):
if i == 1:
height = width = 800
img = Image.new('RGB', (height, width), (255, 0, 0))
draw = ImageDraw.Draw(img)
page.paste(img, (0,0))
im.save('tiffile_b.tif', save_all=True)
Just like #AKX suggested there's no need to create a new image on to paste it onto the current page. Instead draw the rectangle on that page. However, I had to save all the pages in a list and then create a new .tif file out of the new pages in the list.
from PIL import Image, ImageDraw
im = Image.open('tiffile.tif')
frames=[]
for i, page in enumerate(ImageSequence.Iterator(im)):
page = page.copy()
if i == 1:
box = (0, 590, 2272, 2570)
draw = ImageDraw.Draw(page)
draw.rectangle(box, outline=(0), fill=(250))
frames.append(page)
frames[0].save('testfile_b.tif', save_all=True, append_images=frames[1:])
def resolve(img_path):
image = Image.open(img_path)
new_image = Image.new("RGBA", image.size, "WHITE") # Create a white rgba background
new_image.paste(image, (0, 0), image) # Paste the image on the background.
new_image.convert('RGB').save(img_path, "JPEG") # Save as JPEG
enhancedImage = enhance(img_path)
return pytesseract.image_to_string(img_path)
def enhance(img_path):
image1 = cv2.imread(img_path)
#print(image1)
img = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
ret, thresh1 = cv2.threshold(img, 180, 255, cv2.THRESH_BINARY_INV)
#thresh = 50
#im_bw = cv2.threshold(thresh3, thresh, 255, cv2.THRESH_BINARY)[1]
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 2))
erosion = cv2.erode(thresh1, kernel, iterations = 1)
return erosion
I'm trying to solve captcha for above images. Tried converting transparent bg to white and then enchancing the image but results are not correct.
Let me start with the potential problem with your code
def enhance(img_path):
image1 = cv2.imread(img_path)
Now, if you read it with imread the result will be:
You can't read it with pytesseract from the output image.
This is a known issue stated in this answer: cv2 imread transparency gone
As mentioned in the answer:
put a white image behind the transparent one an with that you solve the problem.
We will apply the same technique and now result will be:
As for the second image result will be:
We will be doing the following steps for efficiently reading from the output image:
Resize the image
Apply adaptive-threshold
For the first image the result will be:
For the second image the result will be:
Now when you read it with pytesseract with mode 6 (modes), result will be:
3daab
b42yb
Code:
import cv2
from PIL import Image
from pytesseract import image_to_string
def save_transparent_image(image_path, save_name):
image = Image.open(image_path).convert("RGBA")
canvas = Image.new(mode='RGBA',
size=image.size, color=(255, 255, 255, 255))
canvas.paste(image, mask=image)
canvas.save(save_name, format="PNG")
img_lst = ["o3upS.png", "kGpYk.png"]
for i, img_name in enumerate(img_lst):
save_image = "captcha" + str(i) + ".png"
save_transparent_image(img_name, save_image)
# Step 1: Resize the image
img = cv2.imread(save_image)
(h, w) = img.shape[:2]
img = cv2.resize(img, (w*2, h*2))
# Step 2: Apply adaptive-threshold
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
thr = cv2.adaptiveThreshold(gry, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY, 33, 79)
# Step 3: Read the threshold image
txt = image_to_string(thr, config="--psm 6")
txt = txt.split("\n")[0]
print(txt)
Question Will this code will works for the other captchas?
No, it won't. Unless the captchas are similar to the given example. You need to change the adaptive-threshold's block-size and C parameters, see if it works.
I want to put my pic in my frame.I used this cod :
from PIL import Image
img = Image.open('Pic.jpg')
frame = Image.open('Frame.jpg')
size1 = 354,362
paste_point = 69,339
Pic = img.resize((size1))
frame.paste(img, (paste_point))
frame.show()
When i run the program, my pic doesn't put in my frame.
How can i create a frame in python
your question solution depends always on your pic size and frame size ,so code must be adjusted according to pixel size of your pic
i am giving generic code for your problem maynot fit to your image standards
from PIL import Image
img = Image.open('Pic.jpg')
img_w, img_h = img.size
frame = Image.new('RGBA', (1440, 900), (255, 255, 255, 255))
bg_w, bg_h = frame.size
offset = ((bg_w - img_w) / 2, (bg_h - img_h) / 2)
frame.paste(img, offset)
frame.save('out.png')
Calling
image = Image.open(data)
image.thumbnail((36,36), Image.NEAREST)
will maintain the aspect ratio. But I need to end up displaying the image like this:
<img src="/media/image.png" style="height:36px; width:36px" />
Can I have a letterbox style with either transparent or white around the image?
PIL already has a function to do exactly that:
from PIL import Image, ImageOps
thumb = ImageOps.fit(image, size, Image.ANTIALIAS)
Paste the image into a transparent image with the right size as a background
from PIL import Image
size = (36, 36)
image = Image.open(data)
image.thumbnail(size, Image.ANTIALIAS)
background = Image.new('RGBA', size, (255, 255, 255, 0))
background.paste(
image, (int((size[0] - image.size[0]) / 2), int((size[1] - image.size[1]) / 2))
)
background.save("output.png")
EDIT: fixed syntax error
from PIL import Image
import StringIO
def thumbnail_image():
image = Image.open("image.png")
image.thumbnail((300, 200))
thumb_buffer = StringIO.StringIO()
image.save(thumb_buffer, format=image.format)
fp = open("thumbnail.png", "w")
fp.write(thumb_buffer.getvalue())
fp.close()
Update of Cesar Canassa's answer.
This will create a thumbnail of image.jpg as image_thumb.jpg:
from PIL import Image, ImageOps
fname = 'image.jpg'
size = (48,48)
thumb = ImageOps.fit(Image.open(fname), size, Image.ANTIALIAS)
thumb.save('{}_thumb.jpg'.format(fname[:fname.rfind('.')]), "JPEG")
Or this, maybe... (forgive spaghetti)
from PIL import Image
def process_image(image, size):
if image.size[0] > size[0] or image.size[1] > size[1]:
#preserve original
thumb = image.copy()
thumb.thumbnail(size,Image.ANTIALIAS)
img = thumb.copy()
img_padded = Image.new("RGBA",size)
img_padded.paste(image,(int((size[0]-image.size[0])/2),int((size[1]-image.size[1])/2)))
return img_padded
Why not simply use the resize method ?
from PIL import Image
image = Image.open('/path/to/img.png')
image = image.resize((36,36), Image.ANTIALIAS)
See recommendations for image resizing in this release note:
https://pillow.readthedocs.io/en/stable/releasenotes/5.3.0.html
you can wrap Nadia's answer in this function, which gives you control over size and background.
def make_square(im, min_size=36, fill_color=(255, 255, 255, 0)):
x, y = im.size
size = min(min_size, x, y)
new_im = Image.new('RGBA', (size, size), fill_color)
im.thumbnail((256, 256))
new_im.paste(im, (int((x - size) / 2), int((y -size) / 2))
return new_im