Анатолий Ч. | канал
325 subscribers
1.31K photos
187 videos
17 files
632 links
Канал Анатолия Ч.

Робот: @dot_ch_bot
Чат канала: @wallet_chat
Кто я такой: https://t.me/ch_an/1779

Я: @yandex_links
Download Telegram
Теперь запрещено абсолютно всё
Please open Telegram to view this post
VIEW IN TELEGRAM
Анатолий Ч. | канал
Конкурс. Сиквел. Я придумал как сделать конкурс (🙏) не на двадцать минут, с удвоенным (✖️) призовым фондом, и в котором каждый (🫵) может что-то выиграть. И я готов заплатить ДЕСЯТЬ ТЫСЯЧ РУБЛЕЙ 💰 за нахождение восьми 🎱 точек из сериала. Чтобы вы поверили…
Фриланс-Конкурс-Хакатон

Объявляю фриланс-конкурс-хакатон, в котором я попрошу вас сделать технически нетривиальную фриланс-задачку, которая мне нужна для некоторых целей.

Призовой фонд: 2000₽.

Чтобы вы поверили в СЕРЬЁЗНОСТЬ 👊 моих намерений, ловите ФОТОГРАФИЮ-ПОДТВЕРЖДЕНИЕ 📸 того, что я не шучу. Я показываю два пальца — по одному пальцу за тысячу рублей из призового фонда.

Правила 🚧

0⃣. Через 5 минут я выложу архив input.mp4.zip, содержащий видеофайл input.mp4. Вам необходимо проделать с ними следующие действия:
1⃣. Сделайте видео квадратным, равномерно обрезав его по краям (без сжимания картинки).
2⃣. Удалите из видео аудиодорожку.
3⃣. Уменьшите фреймрейт до 6 кадров в секунду, сохранив при этом длину видео (то есть видео не должно изменить свою длину про хронометражу, просто нужно пропустить некоторые кадры).
4⃣. Сгенерируйте из полученного видео два анимированных .png-файла с разрешениями 42x42 и 100x100 (пропорционально уменьшив изначальный кусок).
5⃣. Обрежьте каждый кадр анимированных .png-файлов по кругу с помощью альфа-канала, чтобы анимашки стали круглыми. При этом для экономии веса файла сотрите данные о цвете снаружи круга (сделав его #000 или #fff).
6⃣. Первый кто отправит мне в личку @yandex_links или в комменты @wallet_chat готовые файлы и будет в состоянии объяснить как это было сделано, становится победителем и получит 1500 российских рублей по СБП или 1800 сербских динар наличными при личной встрече.
7⃣. Оставшиеся 500 российских рублей или 600 сербских динар победитель получит, выполнив дополнительные правки, которые могут понадобиться. Если правок не будет, победитель сразу получит 2000 рублей / 2400 динар.
8⃣. Конкурс действителен до конца 2023 года .
9⃣. В конкурсе могу выиграть я сам 🤑.

🔠. Также у вас есть увлекательная возможность быть дисквалифицированным из конкурса, если вы спросите у меня зачем это нужно. Почему? Потому что это правило мне показалось забавным.
Please open Telegram to view this post
VIEW IN TELEGRAM
Анатолий Ч. | канал
input.mp4.zip
Конкурс закончился

Победил @gosunov. Он уже получил 1500₽. Правки за оставшиеся 500₽, интервью с победителем и публикация рабочего решения будут уже не сегодня.

Хоть многие в комментариях утверждали о тривиальности задачи, всего было прислано 14 неудачных попыток от 4 разных участников. На решение задачи ушло чуть меньше 7 часов, так что можно считать, что эффективность участников-фрилансеров равна 214 рублям в час.

Ставлю в комменты загружаться файлы победителя и ложусь спать. Спокойной ночи!
Анатолий Ч. | канал
Конкурс закончился Победил @gosunov. Он уже получил 1500₽. Правки за оставшиеся 500₽, интервью с победителем и публикация рабочего решения будут уже не сегодня. Хоть многие в комментариях утверждали о тривиальности задачи, всего было прислано 14 неудачных…
Решение

Я немного пообщался с @gosunov, он студент в итмо и занимается олимпиадным программированием. Во время конкурса узнал много нового про формат .png. Его решение состояло из bash-скрипта script.sh, который внутри себя в одном месте запускает python-скрипт:

script.sh
set -e
mkdir frames42x42
mkdir frames42x42masked

ffmpeg -i input.mp4 -an -vf crop=272:272,scale=42:42,fps=6 42x42_fps6_muted.mp4
ffmpeg -i 42x42_fps6_muted.mp4 frames42x42/%05d.png

python3 mask.py
ffmpeg -y -framerate 6 -i frames42x42masked/%05d.png 42x42.apng
mv 42x42.apng 42x42.png


mask.py
from PIL import Image

w = 42
h = 42
x0 = (w - 1) / 2
y0 = (h - 1) / 2

R = min(h, w) / 2 - 1

def crop_to_circle(im):
for x in range(w):
for y in range(h):
dist = ((x0 - x) ** 2 + (y0 - y) ** 2) ** 0.5
if dist > R:
im.putpixel((x, y), (0, 0, 0, 0))

n = 32450
for i in range(1, n + 1):
print('\r%05d/%05d' % (i, n), end='')
im = Image.open('frames%dx%d/%05d.png' % (w, h, i)).convert('RGBA')
crop_to_circle(im)
im.save('frames%dx%dmasked/%05d.png' % (w, h, i))


Оно сделает анимацию для 42x42, для 100x100 понадобится поменять параметры руками и запустить ещё раз.

🥔🥔🥔🥔

Также параллельно с победителем конкурса вчера, прямо на моих глазах пытался закодить задачу @the_tigor, но не успел. В качестве поощрительного приза я купил ему чипсики. Его код состоит из одного python-скрипта, который сразу генерит и 42х42, и 100х100 версии:

tigor.py
import cv2
from PIL import Image, ImageDraw
from tqdm import tqdm
import random

target_fps = 6
video = cv2.VideoCapture('./input.mp4')

first42 = None
first100 = None

sequence42 = []
sequence100 = []

mask = Image.new('L', (272, 272), 0)
draw = ImageDraw.Draw(mask)
draw.ellipse((0, 0, 271, 271), fill=255)

frame_count = video.get(cv2.CAP_PROP_FRAME_COUNT)
nth_frame = video.get(cv2.CAP_PROP_FPS) / target_fps
frame_id = 0
frameids = []

while int(frame_id) < frame_count - nth_frame:
frame_id += nth_frame
frameids.append(frame_id)

def rand_mod(img):
for i in range(4):
width, height = img.size
random_x = random.randint(0, width - 1)
random_y = random.randint(0, height - 1)
random_channel = random.randint(0, 2)

pixel = list(img.getpixel((random_x, random_y)))
if pixel[random_channel] < 255:
pixel[random_channel] += 1
else:
pixel[random_channel] -= 1
img.putpixel((random_x, random_y), tuple(pixel))

for frame_id in tqdm(frameids):
video.set(cv2.CAP_PROP_POS_FRAMES, int(frame_id))
ret, frame = video.read()
if not ret:
break
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

img = Image.fromarray(frame)
cropped = img.crop((104, 0, 376, 272))
round = Image.composite(cropped, Image.new('RGBA', (272, 272)), mask)

img100 = round.resize((100, 100))
img42 = round.resize((42, 42))

rand_mod(img100)
rand_mod(img42)

if first42 is None:
first100 = img100
first42 = img42
else:
sequence100.append(img100)
sequence42.append(img42)

img.close()
cropped.close()
round.close()

def save(first, sequence, name):
first.save(name, optimize=True, compression_level=9, save_all=True,
append_images=sequence, loop=0, duration=int(1000 / target_fps))

save(first42, sequence42, '42.png')
save(first100, sequence100, '100.png')


Про правки я напишу в комменты (и в наш божественный @wallet_chat).
🎵 Wrapped for Artists

Много каналов по соседству публиковали свой Spotify Wrapped. Не думаю, что вам интересно моё увлечение Лидой и Джонибоем, но знали ли вы, что Спотифай делает такую же штуку для артистов?

Раскрываю свои итоги года как Anatoliy Ch. в Spotify.

Слушатели
За год у меня было 764 слушателя из 69 стран. Топ-5 стран по прослушиваниям: Сербия, Нидерланды, США, Германия, Украина. 553 человека услышали меня впервые.

Стримы
У меня 14293 стрима — это 220 часов непрерывного прослушивания моей музыки.

Активность
В этом году мне поставили 103 лайка, а мои песни попали в 21 плейлист. Мои треки шерили другим людям — чаще всего шерили «Музыку для сна в самолёте», «Дай денег» и «Музыку для сна в отеле». И что больше всего меня удивило — у 5 разных человек я попал в топ-5 артистов за этот год!

Астрологи объявили неделю музыкального флекса, самооценка выросла вдвое.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Нет времени объяснять

«Слово пастыря» или «Умницы и умники»?

🗳 ГОЛОСОВАНИЕ 🗳
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Anatoliy Ch.
Какое телешоу лучше?
Anonymous Poll
38%
Слово пастыря
62%
Умницы и умники