Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #16 from yihong0618/master
Browse files Browse the repository at this point in the history
fix requirements.txt and add qr source
Add arg -q, default no qr code, use -q to generate qr
  • Loading branch information
rabbitism authored Sep 29, 2019
2 parents 8114f31 + 4e88f0c commit 55d35c5
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 34 deletions.
39 changes: 32 additions & 7 deletions gadio/crawlers/crawler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import urllib.request

import requests
from MyQR import myqr

from gadio.configs.config import config
from gadio.models.asset import Image, Audio
Expand All @@ -21,9 +22,9 @@ class Crawler():
@staticmethod
def crawl(gadio_id: int):
"""Get timeline and corresponding contents from Gcores website
Arguments:
gadio_id {int} -- gadio id in gcores websites.
gadio_id {int} -- gadio id in gcores websites.
"""
url = api['radio_api_template'].format(radio_id=gadio_id)
print("Extracting information from ", gadio_id)
Expand All @@ -45,7 +46,7 @@ def crawl(gadio_id: int):
#print(cache_dir)
json.dump(parsed, outfile, ensure_ascii=False, indent=4)
return parsed

@staticmethod
def download_image(image: Image, file_dir: str):
try:
Expand Down Expand Up @@ -74,16 +75,18 @@ def download_audio(audio: Audio, file_dir: str):
return

@staticmethod
def download_assets(radio: Radio, file_dir: str):
def download_assets(radio: Radio, file_dir: str, with_quote: bool):
id = str(radio.radio_id)
file_dir = file_dir + os.sep + id
Crawler.download_image(radio.cover, file_dir)
Crawler.download_audio(radio.audio, file_dir + os.sep + 'audio')
for user in radio.users:
Crawler.download_image(user.portrait, file_dir + os.sep + 'users')

for page in radio.timeline.values():
Crawler.download_image(page.image, file_dir)
if with_quote:
Crawler.make_quote_qr_image(page.quote_href, page.image.local_name, file_dir + os.sep + "qr_quotes")

@staticmethod
def get_latest():
Expand All @@ -94,7 +97,7 @@ def get_latest():
parsed = json.loads(content)
id = parsed['data'][0]['id']
return int(id)

@staticmethod
def get_headers(radio: Radio):
offset = config['start_offset']
Expand All @@ -116,4 +119,26 @@ def get_headers(radio: Radio):
links.write("\n\n")
length=len(line)
links.writelines(line)
links.close()
links.close()

@staticmethod
def make_quote_qr_image(text, name, file_dir):
if not os.path.exists(file_dir):
print("Folder", file_dir, 'does not exist. Creating...')
os.makedirs(file_dir)
print("Saving qr_quotes", name)
if text:
name = name.split('.')[0] + ".png"
try:
myqr.run(
text,
version=2,
level="H",
picture=None,
colorized=False,
contrast=1.0,
save_name=name,
save_dir=file_dir,
)
except:
print("wrong qr code")
51 changes: 29 additions & 22 deletions gadio/media/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ def __init__(self, *args, **kwargs):
@staticmethod
def create_cover(radio: Radio):
"""create a cover page for start of video. No text pasted on this page.
Arguments:
radio {Radio} -- Radio
Returns:
image -- a cv2 frame.
"""
Expand All @@ -43,21 +43,21 @@ def create_cover(radio: Radio):
return image

@staticmethod
def create_page(page: Page, radio:Radio):
def create_page(page: Page, radio: Radio):
"""Create a gadio page frame.
Pipeline:
Pipeline:
1. Load image with opencv, use opencv to resize and blur.
2. Convert opencv image to Pillow image
3. Draw text on Pillow image
4. Convert back to opencv image for opencv VideoWriter
Beware that Pillow image and opencv channel orders are different.
Beware that Pillow image and opencv channel orders are different.
Arguments:
page {Page} -- Gadio page
Keyword Arguments:
radio {Radio} -- radio
Returns:
np.array -- An numpy array representing cv2 image.
"""
Expand All @@ -67,6 +67,8 @@ def create_page(page: Page, radio:Radio):
image_dir = os.sep.join(['cache', str(radio.radio_id), radio.cover.local_name])
else:
image_dir = os.sep.join(['cache', str(radio.radio_id), page.image.local_name])
qr_dir = os.sep.join(['cache', str(radio.radio_id), 'qr_quotes', page.image.local_name.split('.')[0] + ".png"])

image = cv2.imread(image_dir)
image_suffix = page.image.suffix
background_image = Frame.expand_frame(image, Frame.width, Frame.height)
Expand All @@ -77,15 +79,15 @@ def create_page(page: Page, radio:Radio):
background_rgb = cv2.cvtColor(background_image, cv2.COLOR_BGR2RGB)
content_rgb = cv2.cvtColor(content_image, cv2.COLOR_BGR2RGB)

#Convert to RGBA for transparency rendering
# Convert to RGBA for transparency rendering
frame = Image.fromarray(background_rgb).convert('RGBA')

mask = Image.new('RGBA', (Frame.width, Frame.height), color=(0, 0, 0, 128))
frame.paste(mask, (0, 0), mask=mask)

left_offset = int(round(245/1920 * Frame.width)) + int(round((550 - content_image.shape[1])/2))
top_offset = int(round(210/1080 * Frame.height)) + int(round((550 - content_image.shape[0])/2))

content_frame = Image.fromarray(content_rgb)
content_image_mask = Image.new('RGBA', (content_image.shape[1], content_image.shape[0]), color=(0, 0, 0, 26))
if (image_suffix == "" or image_suffix.lower() == '.gif'):
Expand All @@ -104,13 +106,18 @@ def create_page(page: Page, radio:Radio):
qr_top_offset = int(round(917/1080 * Frame.height))
frame.paste(logo_image, (logo_left_offset, logo_top_offset), mask=logo_image)
frame.paste(qr_image, (qr_left_offset, qr_top_offset), mask=qr_image)
if os.path.exists(qr_dir):
qr_right_offset = int(round(1700/1920 * Frame.width))
page_qr_image = Image.open(qr_dir).convert('RGBA')
page_qr_image = page_qr_image.resize((86, 86))
frame.paste(page_qr_image, (qr_right_offset, qr_top_offset), mask=page_qr_image)
except:
print("Passing logo rendering due to file error")

draw = ImageDraw.Draw(frame)

text_width_limit = int(round(770 / 1920 * Frame.width))

title_string = Frame.title_wrapper.wrap_string(page.title, text_width_limit)
print('Title:', title_string)
raw_content = page.content
Expand All @@ -123,7 +130,7 @@ def create_page(page: Page, radio:Radio):
title_height = Frame.title_font.getsize_multiline(title_string)[1]
title_space_bottom = int(round(Frame.title_font.size * 0.9))
content_height_limit = int(round(574 / 1080 * Frame.height)) - title_height - title_space_bottom

content_space = int(round(Frame.content_font.size * 0.8))
actual_content_height = Frame.content_font.getsize_multiline(content_string, spacing=content_space)[1]
while (actual_content_height > content_height_limit):
Expand All @@ -132,25 +139,25 @@ def create_page(page: Page, radio:Radio):
content_wrapper = Wrapper(Frame.content_font)
content_string = content_wrapper.wrap_string(raw_content, text_width_limit)
actual_content_height = Frame.content_font.getsize_multiline(content_string, spacing=content_space)[1]
#print(actual_content_height)
# print(actual_content_height)

print(content_string)
draw.text((text_left_offset, text_top_offset), title_string, config['gcores_title_color'], font=Frame.title_font)
draw.text((text_left_offset, text_top_offset + title_height + title_space_bottom), content_string, config['gcores_content_color'], font=Frame.content_font, spacing=content_space)
#Reset content_wrapper and content_font

# Reset content_wrapper and content_font
Frame.content_font = ImageFont.truetype(config['content_font'], config['content_font_size'], encoding="utf-8")
Frame.content_wrapper = Wrapper(Frame.content_font)

cv2charimg = np.array(frame)
result = cv2.cvtColor(cv2charimg, cv2.COLOR_RGB2BGR)
#cv2.imwrite('test.jpg',result)
#cv2.waitKey()
# cv2.imwrite('test.jpg',result)
# cv2.waitKey()
return result

@staticmethod
def expand_frame(image, target_width, target_height):
"""Expand a frame so it is larger than the rectangle
"""Expand a frame so it is larger than the rectangle
Arguments:
image {Image} -- cv2 image
Expand All @@ -171,7 +178,7 @@ def expand_frame(image, target_width, target_height):
actual_width = max(int(image.shape[1] / ratio), target_width)
actuai_height = max(int(image.shape[0] / ratio), target_height)
result = cv2.resize(image, (actual_width, actuai_height),
interpolation=cv2.INTER_CUBIC)
interpolation=cv2.INTER_CUBIC)
left = int((result.shape[1] - target_width) / 2)
right = left + target_width
top = int((result.shape[0] - target_height) / 2)
Expand All @@ -181,12 +188,12 @@ def expand_frame(image, target_width, target_height):
@staticmethod
def shrink_frame(image, target_width, target_height):
"""Shrink a frame so it is smaller than the rectangle
Arguments:
image {Image} -- np array
target_width {int} -- target width of rectangle
target_height {int} -- target height of rectangle
Returns:
np.array -- resized image
"""
Expand All @@ -203,4 +210,4 @@ def shrink_frame(image, target_width, target_height):
@staticmethod
def shrink_font(font, font_family):
result_font = ImageFont.truetype(font_family, font.size-2, encoding="utf-8")
return result_font
return result_font
16 changes: 11 additions & 5 deletions gcores.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,33 @@
from gadio.text.text import *
import sys

def main(id: int, skip_crawling: bool):

def main(id: int, skip_crawling: bool, with_quote: bool):
parsed_json = Crawler.crawl(id)
cache_dir = os.sep.join([os.curdir, 'cache', str(id), 'data.json'])
with open(cache_dir, 'r', encoding='utf-8') as file:
radio = Radio.load_from_json(parsed_json)
if (not skip_crawling):
Crawler.download_assets(radio, os.curdir+os.sep+'cache')
Crawler.download_assets(radio, os.curdir+os.sep+'cache', with_quote)
Video.create_video(radio)

if __name__ == "__main__":
skip_crawling = False
if (len(sys.argv) == 1 or sys.argv[1]=='-s'):
with_quote = False
if (len(sys.argv) == 1 or sys.argv[1] == '-s' or sys.argv[1] == '-q'):
if "-q" in sys.argv:
with_quote = True
print("----------")
print("Start to create the latest gadio video...")
id = Crawler.get_latest()
print(id)
main(id, False)
main(id, False, with_quote)
else:
title = sys.argv[1]
skip_crawling = False
if (len(sys.argv) > 2):
if ("-s" in sys.argv):
skip_crawling = True
main(int(title), skip_crawling)
elif "-q" in sys.argv:
with_quote = True
main(int(title), skip_crawling, with_quote)
Binary file modified requirements.txt
Binary file not shown.

0 comments on commit 55d35c5

Please sign in to comment.