欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用Python監(jiān)控NASA TV直播畫面的實(shí)現(xiàn)步驟

 更新時(shí)間:2021年05月20日 10:40:59   作者:Python中文社區(qū)  
本文分享一個(gè)名為"Spacestills"的開(kāi)源程序,它可以用于查看 NASA TV 的直播畫面(靜止幀)

演示地址:

https://replit.com/@PaoloAmoroso/spacestills

這是一個(gè)具有GUI的簡(jiǎn)單系統(tǒng),它訪問(wèn)feed流并從Web下載數(shù)據(jù)。該程序僅需350行代碼,并依賴于一些開(kāi)源的Python庫(kù)。

關(guān)于程序

Spacestills會(huì)定期從feed流中下載NASA TV靜止幀并將其顯示在GUI中。
該程序可以校正幀的縱橫比,并將其保存為PNG格式。它會(huì)自動(dòng)下載最新的幀,并提供手動(dòng)重新加載,禁用自動(dòng)重新加載或更改下載頻率的選項(xiàng)。
Spacestillsis是一個(gè)比較初級(jí)的版本,但是它可以做一些有用的事情:捕獲并保存NASA TV直播的太空事件圖像。太空愛(ài)好者經(jīng)常在社交網(wǎng)絡(luò)或論壇共享他們從NASA TV手動(dòng)獲取的屏幕截圖。Spacestills節(jié)省了使用屏幕捕獲工具的時(shí)間,并保存了可供共享的圖像文件。您可以在Replit上在線運(yùn)行Spacestills。

開(kāi)發(fā)環(huán)境

筆者用Replit開(kāi)發(fā)了Spacestills。Replit是云上的開(kāi)發(fā),部署和協(xié)作環(huán)境,它支持包括Python在內(nèi)的數(shù)十種編程語(yǔ)言和框架。作為Chrome操作系統(tǒng)和云計(jì)算愛(ài)好者,筆者非常喜歡Replit,因?yàn)樗梢栽跒g覽器中完全正常運(yùn)行,無(wú)需下載或安裝任何內(nèi)容。

資源和依賴包

Spacestills依賴于一些外部資源和Python庫(kù)。

NASA TV feed 流

肯尼迪航天中心的網(wǎng)站上有一個(gè)頁(yè)面,其中包含精選的NASA視頻流,包括NASA電視公共頻道。feed流顯示最新的靜止幀并自動(dòng)更新。
每個(gè)feed都帶有三種尺寸的幀,Spacestills依賴于具有704x408像素幀的最大NASA TV feed流。最大更新頻率為每45秒一次。因此,檢索最新的靜止幀就像從feed流的URL下載JPEG圖像一樣簡(jiǎn)單。
原始圖像被垂直拉伸,看起來(lái)很奇怪。因此,該程序可以通過(guò)壓縮圖像并生成未失真的16:9版本來(lái)校正縱橫比。

Python

因PySimpleGUI的原因需要安裝 Python 3.6 版本。

第三方庫(kù)

  • Pillow:圖像處理
  • PySimpleGUI:GUI框架(Spacestills使用Tkinter后端)
  • Request:HTTP請(qǐng)求

完整代碼

from io import BytesIO
from datetime import datetime, timedelta
from pathlib import Path
import requests
from requests.exceptions import Timeout
from PIL import Image
import PySimpleGUI as sg


FEED_URL = 'https://science.ksc.nasa.gov/shuttle/countdown/video/chan2large.jpg'

# Frame size without and with 16:9 aspect ratio correction
WIDTH = 704
HEIGHT = 480
HEIGHT_16_9 = 396

# Minimum, default, and maximum autoreload interval in seconds
MIN_DELTA = 45
DELTA = MIN_DELTA
MAX_DELTA = 300


class StillFrame():
    """Holds a still frame.
    
    The image is stored as a PNG PIL.Image and kept in PNG format.
    Attributes
    ----------
        image : PIL.Image
            A still frame
        original : PIL.Image
            Original frame with wchich the instance is initialized, cached in case of
            resizing to the original size
    
    Methods
    -------
        bytes : Return the raw bytes
        resize : Resize the screenshot
        new_size : Calculate new aspect ratio
    """

    def __init__(self, image):
        """Convert the image to PNG and cache the converted original.
        Parameters
        ----------
            image : PIL.Image
                Image to store
        """
        self.image = image
        self._topng()
        self.original = self.image

    def _topng(self):
        """Convert image format of frame to PNG.
        Returns
        -------
            StillFrame
                Frame with image in PNG format
        """
        if not self.image.format == 'PNG':
            png_file = BytesIO()
            self.image.save(png_file, 'png')
            png_file.seek(0)
            png_image = Image.open(png_file)
            self.image = png_image
        return self

    def bytes(self):
        """Return raw bytes of a frame image.
        
        Returns
        -------
            bytes
                Byte stream of the frame image
        """
        file = BytesIO()
        self.image.save(file, 'png')
        file.seek(0)
        return file.read()

    def new_size(self):
        """Return image size toggled between original and 16:9.
        
        Returns
        -------
            2-tuple
                New size
        """
        size = self.image.size
        original_size = self.original.size
        new_size = (WIDTH, HEIGHT_16_9) if size == original_size else (WIDTH, HEIGHT)
        return new_size

    def resize(self, new_size):
        """Resize frame image.
        
        Parameters
        ----------
            new_size : 2-tuple
                New size
        Returns
        -------
            StillFrame
                Frame with image resized
        """
        if not(self.image.size == new_size):
            self.image = self.image.resize(new_size)
        return self
    

def make_blank_image(size=(WIDTH, HEIGHT)):
    """Create a blank image with a blue background.
    
    Parameters
    ----------
        size : 2-tuple
            Image size
    
    Returns
    -------
        PIL.Image
            Blank image
    """
    image = Image.new('RGB', size=size, color='blue')
    return image


def download_image(url):
    """Download current NASA TV image.
    Parameters
    ----------
        url : str
            URL to download the image from
    
    Returns
    -------
        PIL.Image
            Downloaded image if no errors, otherwise blank image
    """
    try:
        response = requests.get(url, timeout=(0.5, 0.5))
        if response.status_code == 200:
            image = Image.open(BytesIO(response.content))
        else:
            image = make_blank_image()
    except Timeout:
        image = make_blank_image()
    return image


def refresh(window, resize=False, feed=FEED_URL):
    """Display the latest still frame in window.
    
    Parameters
    ----------
        window : sg.Window
            Window to display the still to
        feed : string
            Feed URL
    
    Returns
    -------
        StillFrame
            Refreshed screenshot
    """
    still = StillFrame(download_image(feed))
    if resize:
        still = change_aspect_ratio(window, still, new_size=(WIDTH, HEIGHT_16_9))
    else:
        window['-IMAGE-'].update(data=still.bytes())
    return still


def change_aspect_ratio(window, still, new_size=(WIDTH, HEIGHT_16_9)):
    """Change the aspect ratio of the still displayed in window.
    
    Parameters
    ----------
        window : sg.Window
            Window containing the still
        new_size : 2-tuple
            New size of the still
    
    Returns
    -------
        StillFrame
            Frame containing the resized image
    """
    resized_still = still.resize(new_size)
    window['-IMAGE-'].update(data=resized_still.bytes())
    return resized_still


def save(still, path):
    """Save still to a file.
    Parameters
    ----------
        still : StillFrame
            Still to save
        path : string
            File name
    
    Returns
    -------
        Boolean
            True if file saved with no errors
    """
    filename = Path(path)
    try:
        with open(filename, 'wb') as file:
            file.write(still.bytes())
        saved = True
    except OSError:
        saved = False
    return saved


def next_timeout(delta):
    """Return the moment in time right now + delta seconds from now.
    Parameters
    ----------
        delta : int
            Time in seconds until the next timeout
    
    Returns
    -------
        datetime.datetime
            Moment in time of the next timeout
    """
    rightnow = datetime.now()
    return rightnow + timedelta(seconds=delta)


def timeout_due(next_timeout):
    """Return True if the next timeout is due.
    Parameters
    ----------
        next_timeout : datetime.datetime
    
    Returns
    -------
        bool
            True if the next timeout is due
    """
    rightnow = datetime.now()
    return rightnow >= next_timeout


def validate_delta(value):
    """Check if value is an int within the proper range for a time delta.
    Parameters
    ----------
        value : int
            Time in seconds until the next timeout
    
    Returns
    -------
        int
            Time in seconds until the next timeout
        bool
            True if the argument is a valid time delta
    """
    isinteger = False
    try:
        isinteger = type(int(value)) is int
    except Exception:
        delta = DELTA
    delta = int(value) if isinteger else delta
    isvalid = MIN_DELTA <= delta <= MAX_DELTA
    delta = delta if isvalid else DELTA
    return delta, isinteger and isvalid


LAYOUT = [[sg.Image(key='-IMAGE-')],
          [sg.Checkbox('Correct aspect ratio', key='-RESIZE-', enable_events=True),
           sg.Button('Reload', key='-RELOAD-'),
           sg.Button('Save', key='-SAVE-'),
           sg.Exit()],
          [sg.Checkbox('Auto-reload every (seconds):', key='-AUTORELOAD-',
                       default=True),
           sg.Input(DELTA, key='-DELTA-', size=(3, 1), justification='right'),
           sg.Button('Set', key='-UPDATE_DELTA-')]]


def main(layout):
    """Run event loop."""
    window = sg.Window('Spacestills', layout, finalize=True)
    current_still = refresh(window)

    delta = DELTA
    next_reload_time = datetime.now() + timedelta(seconds=delta)

    while True:
        event, values = window.read(timeout=100)
        if event in (sg.WIN_CLOSED, 'Exit'):
            break
        elif ((event == '-RELOAD-') or
                (values['-AUTORELOAD-'] and timeout_due(next_reload_time))):
            current_still = refresh(window, values['-RESIZE-'])
            if values['-AUTORELOAD-']:
                next_reload_time = next_timeout(delta)
        elif event == '-RESIZE-':
            current_still = change_aspect_ratio(
                window, current_still, current_still.new_size())
        elif event == '-SAVE-':
            filename = sg.popup_get_file(
                'File name', file_types=[('PNG', '*.png')], save_as=True,
                title='Save image', default_extension='.png')
            if filename:
                saved = save(current_still, filename)
                if not saved:
                    sg.popup_ok('Error while saving file:', filename, title='Error')
        elif event == '-UPDATE_DELTA-':
            # The current cycle should complete at the already scheduled time. So
            # don't update next_reload_time yet because it'll be taken care of at the
            # next -AUTORELOAD- or -RELOAD- event.
            delta, valid = validate_delta(values['-DELTA-'])
            if not valid:
                window['-DELTA-'].update(str(DELTA))

    window.close()
    del window


if __name__ == '__main__':
    main(LAYOUT)

以上就是用 Python 監(jiān)控 NASA TV 直播畫面的實(shí)現(xiàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于Python 監(jiān)控 NASA TV 直播畫面的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 只需7行Python代碼玩轉(zhuǎn)微信自動(dòng)聊天

    只需7行Python代碼玩轉(zhuǎn)微信自動(dòng)聊天

    今天小編就為大家分享一篇關(guān)于只需7行Python代碼玩轉(zhuǎn)微信自動(dòng)聊天,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • django上傳圖片并生成縮略圖方法示例

    django上傳圖片并生成縮略圖方法示例

    這篇文章主要介紹了django上傳圖片并生成縮略圖方法示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • 使用rst2pdf實(shí)現(xiàn)將sphinx生成PDF

    使用rst2pdf實(shí)現(xiàn)將sphinx生成PDF

    這篇文章主要介紹了使用rst2pdf實(shí)現(xiàn)將sphinx生成PDF的相關(guān)資料,以及使用過(guò)程用遇到的錯(cuò)誤的處理方法,非常的全面,需要的朋友可以參考下
    2016-06-06
  • python3 實(shí)現(xiàn)調(diào)用串口功能

    python3 實(shí)現(xiàn)調(diào)用串口功能

    今天小編就為大家分享一篇python3 實(shí)現(xiàn)調(diào)用串口功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • 使用Python制作一個(gè)批量查詢搜索排名工具

    使用Python制作一個(gè)批量查詢搜索排名工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python制作一個(gè)批量查詢搜索排名工具,并且不需要花費(fèi)任何費(fèi)用,裝上python開(kāi)發(fā)環(huán)境即可,需要的可以參考一下
    2023-06-06
  • 一文詳解凱撒密碼的原理及Python實(shí)現(xiàn)

    一文詳解凱撒密碼的原理及Python實(shí)現(xiàn)

    凱撒密碼是古羅馬愷撒大帝用來(lái)對(duì)軍事情報(bào)進(jìn)行加密的算法,它采用了替換方法對(duì)信息中的每一個(gè)英文字符循環(huán)替換為字母表序列該字符后面第三個(gè)字符。本文主要為大家講解了凱撒密碼的原理及實(shí)現(xiàn),需要的可以參考一下
    2022-08-08
  • Anaconda中利用conda創(chuàng)建、激活、刪除、添加新環(huán)境

    Anaconda中利用conda創(chuàng)建、激活、刪除、添加新環(huán)境

    在使用Python開(kāi)發(fā)項(xiàng)目或者編寫腳本的時(shí)候通常需要建立不同版本的Python的虛擬環(huán)境,本文主要介紹了Anaconda中利用conda創(chuàng)建、激活、刪除、添加新環(huán)境,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • python tkinter界面居中顯示的方法

    python tkinter界面居中顯示的方法

    今天小編就為大家分享一篇python tkinter界面居中顯示的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • python能自學(xué)嗎

    python能自學(xué)嗎

    在本篇文章里小編給大家整理了關(guān)于python如何自學(xué)的相關(guān)理論性文章,有需要的朋友們可以參考下。
    2020-06-06
  • Python pip install如何修改默認(rèn)下載路徑

    Python pip install如何修改默認(rèn)下載路徑

    這篇文章主要介紹了Python pip install如何修改默認(rèn)下載路徑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論