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

fix requirements.txt and add qr source #16

Merged
merged 2 commits into from
Sep 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.