Pull to refresh

Comments 26

А теперь внимание, вопрос на миллион: если всё так тривиально, то почему аналогичную нейросеточку тупо не сделают на сайте, который требует эти фотографии? Ну, чтобы убрать из процесса вот таких вот посредников?

P.S.

Хоть бы самыми ржачными фоточками «до» поделились!

Там же одно из основных требований, что фотография должна быть НЕ обработанная.

Это где так? Оо
Фото ателье когда делают фото на визу её ретушируют, и никаких проблем не возникает

консулу маме мы ничего не скажем".
Что на незначительные массовые нарушения закрывают глаза - ещё не оправдание этих нарушений. И да, иногда всё-таки могут забраковать.

Это где так?

Чуть менее, чем везде.

(Но, как всегда — требование есть, а проверки на соответствие ему — нет.)

Ну вот, например, для визы в Японию в требованиях к фотографии прямо указано: "Do NOT use filters". Мне казалось, для визы в США я тоже аналогичное требование видел, но чё-то на их сайте не найду - может, и впрямь, показалось. Разве вот в разделе FAQ есть про красные глаза:

Can I remove the red-eye from my photo?

It is acceptable to use the red-eye reduction option on your digital camera when you are taking the photo.  However, you cannot use any photo editing tool to digitally remove the red-eye from your photo. In general, you are not allowed to digitally enhance or alter the photo to change your appearance in any way.

Во всяком случае, обработка типа "resize, rotate and crop" в явном виде позволяется. Что до удаления фона - я не осилил понять, вроде, это "digitally enhance", но не "change your appearance". Ну и отписка "а мы рассмотрим, и, может, отвергнем".

Хоть бы самыми ржачными фоточками «до» поделились!

Спасибо за идею :)

Фоточки до

Сразу вижу брак: на лице тени.

Примитивный редактор "обрезать/подогнать под нужный размер", вроде, делают, а удаление фона, да чтоб корректно обработало всю волосню по краям - на хера? Так трудно встать на фоне белой стены и щёлкнуть смартфоном физиономию?

Не только лишь все имеют белую стену с птдходящим освещением. Мало кто может, чтобы белая стена была белым фоном, а не серым с тенью, например.

Мало кто может

Кто не может сам - обращается к специалистам.

А где полные исходники? Мне, например, совершенно не хочется позволять кому попало связывать мой аккаунт в Телеграме с моим фото.

Человек сделал удобный и бесплатный сервис, который лучше некоторых платных аналогов, а вам и этого мало...

не хочется позволять кому попало связывать мой аккаунт в Телеграме с моим фото.

Тащмаёр, кажется, этот гражданин раскусил вашу гениальную идею!

ага, и нет интеграции с госуслугами и max!

Я может отстал от жизни, но разве в фотоателье не печатают фотки под заданные размеры? Откуда взялись сайты с услугами за 5-12 долларов? Или они высылают бумажные фотки на адрес?

Кейс такой:

Вы заполняете форму на электронную визу и вам надо прикрепить фото - вы дома, а фотоателье далеко.

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

Нет, бумагу не шлют. Просто готовый файл под нужные требования. По сути, платишь за обрезку и фон

UFO landed and left these words here

А я пользуюсь вот этой программой. Ну давно не пользовался, но все же. https://www.fourmilab.ch/netpbm/passport_photo/ Эта программа разработана бывшим владельцем AUTOCAD. https://en.wikipedia.org/wiki/John_Walker_(programmer)

У меня есть старенький цветной принтер Canon Selphy CP900. Он очень качественно печатает маленькие фотки 148 x 100 мм. Принтер рекомендую. Качество высше всяких похвал. Печатает на специальной бумаге.

Короче, я фотографирую на карманный фотоаппарат, обрабатываю этой программой, затем печатаю на принтере и разрезаю. Программа работает на Linux по крайней мере. Не знаю как с Windows .

Вообще замечательный дядька. Рекомендую ознакомиться с сайтом. Много интересного.

Недавно делал для себя, чтобы обрезанную в нужных пропорциях цифровую фотографию распечатать в нужном размере на фотопринтере. На скорую руку, багов особо не ловил, но "у меня всё работает". На Linux работает, на Windows не проверял, но тоже должно. Нужны Python 3.x, OpenCV и NumPy (всё ставится моментально из репозиториев или через pip, Python на Linux обычно и так есть уже).

Код
#!/usr/bin/env python3

import cv2
import numpy as np
import sys

def tile(img_in, img_size_mm, paper_size, paper_size_unit = "in", bgvalue = 255):
    img_size = np.array(img_size_mm, dtype=np.float64) # w, h
    paper_size = np.array(paper_size, dtype=np.float64) # w, h
    if paper_size_unit == "in": paper_size *= 25.4
    elif paper_size_unit != "mm":
        raise Exception("Unknown paper unit size, use in or mm")

    n_cols_rows = (paper_size // img_size).astype(np.uint64)
    gaps = (paper_size % img_size) / (n_cols_rows + 1) # w_gap, h_gap
    
    h, w, _ = img_in.shape # h, w
    mm2px = h / img_size[1]
    paper_size_px = (paper_size * mm2px).astype(np.uint64)
    gaps_px = (gaps * mm2px).astype(int)

    img_out = np.full(shape=(paper_size_px[1], paper_size_px[0], 3), fill_value = bgvalue, dtype = np.uint8)

    cur_top = gaps_px[1]
    for row in range(n_cols_rows[1]):
        cur_left = gaps_px[0]
        for col in range(n_cols_rows[0]):
            img_out[cur_top : int(cur_top + h), cur_left : int(cur_left + w)] = img_in
            cur_left += int(w + gaps_px[0])
        cur_top += int(h + gaps_px[1])

    return img_out

if __name__ == '__main__':
    try:
        input_name = sys.argv[1]
        output_name = sys.argv[2]
        input_size = sys.argv[3:5]
        paper_size = sys.argv[5:7]
        paper_size_unit = sys.argv[7] if len(sys.argv) > 7 else "in"
        paper_bgvalue = sys.argv[8] if len(sys.argv) > 8 else 255
    except Exception as e:
        print(f"{sys.argv[0]} input.jpg output.jpg <input width mm> <input height mm> <paper width> <paper height> <paper unit (in or mm)> <fill value (0~255)>")
        sys.exit(0)

    img = cv2.imread(input_name)
    img_t = tile(img, input_size, paper_size, paper_size_unit, paper_bgvalue)
    cv2.imwrite(output_name, img_t)

Чтобы разложить нижеприведённую фотографию на лист размером 4 на 6 дюймов (варварство, но что я с ним могу сделать, разве что каждый раз умножать на 25.4... зато размеры исходника задаются только в миллиметрах!), и каждая напечатанная фотография была 30 на 40 мм, на чёрном фоне:

./tile.py input.jpg output.jpg 30 40 4 6 in 0

Результат
alt
title
alt
title

Полезная штука, особенно для виз

Минутка паранои: отправлять фото, да еще в формате "как на документы" непонятному телеграмм-боту ... На выходе владелец бота получает базу данных "эккаунт телеграмм - фотография", ну а дельше... сами додумайте кому и зачем может пригодится такая база)

Нужно отослать штук 500 фотографий с каждого аккаунта. Пусть сами потом решают, зачем может пригодиться такая база ;)

try:
auth_data = validateand_extract_auth(Authorization, BOT_TOKEN)
except ValueError as e:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f"Invalid auth data: {e}")

У FastApi есть механизм Depends, который решает эту задачу заметно удобнее – один раз прописываешь для роутера и дальше в каждой ручке внутри роутера будет проверка токена и уже готовый объект инит даты

Скрытый текст

def parse_init_data(init_data: str) -> TelegramInitData:
    parsed_query = urllib.parse.parse_qs(init_data)

    data = {}
    for key in parsed_query:
        data[key] = parsed_query[key][0]
    data["user"] = json.loads(data["user"])

    return TelegramInitData.validate(data)


def validate_telegram_data(query_string: str) -> bool:
    data = dict(urllib.parse.parse_qsl(query_string))

    received_hash = data.pop("hash", None)
    if received_hash is None:
        return False

    data_check_string = "\n".join(
        f"{key}={urllib.parse.unquote(value)}" for key, value in sorted(data.items())
    )

    secret_key = hmac.new(
        key="WebAppData".encode("utf-8"),
        msg=BOT_TOKEN.encode("utf-8"),
        digestmod=hashlib.sha256,
    ).digest()

    check_hash = hmac.new(
        key=secret_key, msg=data_check_string.encode("utf-8"), digestmod=hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(check_hash, received_hash)
async def decode_auth_header(request: Request):
    expected_header = "authorization"

    if expected_header not in request.headers:
        raise HTTPException(status_code=401, detail="Authorization header is required")

    token_encoded = request.headers[expected_header].removeprefix("TMA ")
    token = base64.b64decode(token_encoded).decode()

    if not validate_telegram_data(token):
        raise HTTPException(status_code=401, detail="Invalid initData")

    init_data = parse_init_data(token)

    request.state.data = init_data

    return init_data

Мой пример инит дату в Base64 в Authorization: TMA .... передает, но думаю концепт понятен.


И пример испоьзования:

app.include_router(router, dependencies=[Depends(decode_auth_header)])

@router.post("/")
async def something(request: Request):
  user_id = request.state.data.user.id 
Sign up to leave a comment.

Articles