整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          關于畫面構成與layout(上) - 平松禎史講la

          關于畫面構成與layout(上) - 平松禎史講layout

          者:mjn/Anitama 封面來源:GAINAX

          layout是分鏡到原畫的過渡環節,分鏡大多數很小很草沒有細節,在layout步驟決定一個鏡頭中所有細節和背景,也關系到人物動作。

          如何設計layout是老大難的問題,很多人問,于是這次平松禎史專門在博客寫了一篇文章來講解layout,作為一個超老手原畫的意見,本文無論對于業內還是愛好者,都非常有學習參考的價值。

          需要注意的一點是,當下國產動畫很多時候都忽視layout的作用,分鏡干了layout的工作,原畫只管人物動作,這樣不但動作本身銜接性不好,而且整體透視感空間感非常差。

          下文是文章的節選翻譯。

          原文地址:http://ameblo.jp/tadashi-hiramatz/entry-12110925284.html

          gainax《飛躍巔峰》的分鏡、layout、原畫、成片的實例

          入江泰浩在推特上公開的《請問要來點兔子》第二季11集的layout

          問的最多的問題是“如何畫layout”,其實并不是那么難的問題。

          只是因為所包含的要素太多,不同作品不同場合下,意義會有所不同,原畫也一樣,一般論無法充分解釋,解釋了還可能產生誤解。所以,我覺得新人原畫還是在了解基本知識的基礎上,進行實戰學習比較好。(譯者注:本來layout的意思僅僅是構圖,但是現在很多情況下layout繪制者同時需要完成草原畫,即第一原畫,所以第一原畫和構圖統稱為layout的情況較多。)

          動畫制作的作業工程每一個環節都有它的目的,不確切明白相關環節的意義,做出來的東西會讓觀眾看不懂,有些必要的東西無法正確傳達給觀眾,進而導致作品的失敗。

          所以明白畫面構成、layout是什么、為什么,這點是必須的。

          雖然無法用一般論說明清楚,我還是試試看吧,雖然可能會含有個人的主觀想法。

          layout是分鏡之后的工程,下面的基礎都是分鏡合適的情況,要是分鏡有問題那怎么辦?那就是另外的問題了。

          (譯者注,國內對于分鏡這個詞也有歧義,在某些國內動畫公司里,分鏡等同于layout,片尾職位表中的分鏡實際干了畫面構成layout的活,原畫則是單純做人物動作的繪制,不同于日式制作流程,日式流程中原畫負責layout,整個畫面的掌握權都在原畫手上。這也是比較科學合理的分配。)

          地點 時間 氣氛——layout必須的三要素

          layout是構成故事的影像制作的第一步,也是從演出到原畫的渡橋。

          演出負責把腳本做成分鏡,把文字做成可以影像化的一卡一卡連續小設計圖,正確理解讀取腳本是前提。(譯者注:雖然在片尾我們經??吹窖莩龊头昼R(絵コンテ)是分開寫的,但是在動畫制作早期,分鏡和演出不分開,單記演出名,并不設分鏡職位,做了分鏡的人理所當然負責這集的演出工作,所以這里分鏡和演出統稱為演出,和anitama談論的演出、演出tag是一個意思。現在因為種種原因演出和分鏡經常是分開的,但是考慮到分鏡演出對整體作業的影響我們還是統稱為演出。)

          對于原畫則是以正確理解分鏡、讀取演出意圖為前提,才能畫layout。

          5W1H——“什么時候?在哪里?誰?在做什么?為了什么?怎么做?”是必須基本明確的,總結成簡要三點則是:地點、時間、氣氛。

          把這三點明確恰當得表現出來就是layout的目的。所以說,要畫某一鏡頭之前,不明白這個場景和發生在這個場景的故事是畫不了的,最起碼不明白前后鏡頭的關系是不能畫的。

          簡單說明這三要素。

          - 地點——也就是舞臺。在哪個地方。這個地方有什么。天氣怎么樣。

          - 時間——上午下午黃昏夜晚,具體是哪個時間帶。時間是如何變化的。

          - 氣氛——人物是什么樣的心情、目的、動作。即使是人物不出現的的鏡頭也能包含氣氛。

          分鏡并不需要把上述要素表現得太清楚,layout本身就需要原畫讀取理解分鏡之后收集影像中的必要要素。雖然寫的是演出到原畫的渡橋,其實是把之后的所有作業工程都交渡過去了。

          演出(分鏡)上的三要素是“畫面大小、被拍人物的角度、視野角”,三者本身之間密切相關、相互影響。

          為什么是特寫?為什么用仰視的鏡頭?為什么用望遠構圖?等等之類的都應該有其演出意圖。

          過于追求細節估計說不完說不盡,這次就概括成“地點、時間、氣氛”。

          最重要的是氣氛。地點、時間、動作都應該為氣氛的表現服務。氣氛、人物的感覺不變化,人物的動作也不會產生。即使機械作畫也一樣有感覺和趨勢存在。

          演出方面,氣氛、感覺不變化,鏡頭也不變化。雖然不同演出家的鏡頭使用方法有差別,但是多數都是基于固定鏡頭(FIX),要使鏡頭發生變化必須有讓其產生變化的必要性存在。人物的動作也同理。

          分鏡畫得無論多細致還是多草多簡單,都應該能讓工程后面的制作人員能明白這個作品想要表現什么、這個場景事件有什么意圖、鏡頭需要表現出怎樣的演出效果、登場人物的心情感受等等。場景不同,可能分鏡三要素的優先順序有不同。會話場景和打斗場景必要的要素肯定有不同,不同鏡頭之間也可能有不同。

          本文僅供Anitama發表,任何單位或個人,不得以任何形式刊載本文的部分或全部內容。

          官方網站:http://www.anitama.cn

          官方微博:@AnimeTamashii

          微信公眾號:AniTama

          合作郵箱:bd@anitama.cn

          原文: m.anitama.cn/article/1a3d15c14218472a?utm_source=toutiao

          過本文章,你可以掌握以下內容:

          1. Pyside6 Layout介紹
          2. Pyside6 Layout布局解釋及示例
          3. 自定義Layout,實現部件自動換行

          1、Pyside6 Layout介紹

          QtWidgets.QLayout是Qt中用于管理窗口或對話框中小部件(控件)布局的基類。它是一個抽象基類,定義了所有布局類共有的接口和行為。QLayout及其子類的主要作用是自動管理小部件的位置和大小,以便于創建整潔和靈活的圖形用戶界面(GUI),對于復雜界面布局是很重要的,主要作用包括:

          • 自動管理小部件位置:QLayout自動計算小部件的位置,使得小部件根據布局規則排列,無需手動指定每個小部件的具體位置。
          • 自動調整大小:當窗口大小變化時,QLayout能夠自動調整其管理的小部件的大小和位置,確保布局的一致性和響應性。
          • 簡化界面設計:通過使用布局,開發者可以更加專注于界面的結構設計,而不是具體的位置和大小調整,從而簡化了界面設計過程。
          • 支持嵌套:布局可以嵌套使用,即一個布局可以包含其他布局,這允許創建復雜的界面結構

          Layout繼承關系圖

          2、Pyside6 Layout布局解釋及示例

          以下是繼承自QtWidgets.QLayout的布局,每種布局有對應的行為。

          布局

          行為

          對應html

          QHBoxLayout

          線性水平布局

          類似于display: flex; flex-direction: row;的Flexbox布局

          QVBoxLayout

          線性垂直布局

          類似于display: flex; flex-direction: column;的Flexbox布局

          QGridLayout

          在可轉位網格 XxY 中

          類似于html的table行和列

          QStackedLayout

          堆疊 (z) 于彼此前面

          類似于css的z-index,并控制隱藏顯示效果

          QHBoxLayout

          QHBoxLayout是Qt中的一個布局管理器類,用于按水平方向排列小部件。它繼承自QLayout,提供了一種簡便的方式來自動管理窗口或對話框中小部件的位置和大小。使用QHBoxLayout,可以將小部件從左到右依次排列,而不需要手動指定每個小部件的具體位置。

          QHBoxLayout繼承關系圖

          簡單的示例如下:

          import sys
          from PySide6.QtWidgets import *
          class MainWindow(QMainWindow):
              def __init__(self):
                  super(MainWindow, self).__init__()
                  self.setWindowTitle("QHBoxLayout之水平布局")
                  self.setMinimumSize(400,300)
                  layout=QHBoxLayout()
                  layout.addWidget(QPushButton("1"))
                  layout.addWidget(QPushButton("2"))
                  layout.addWidget(QPushButton("3"))
                  widget=QWidget()
                  widget.setLayout(layout)
                  self.setCentralWidget(widget)
          
          if __name__=='__main__':
              app=QApplication(sys.argv)
              window=MainWindow()
              window.show()
              app.exec()

          QHBoxLayout示例效果圖

          QVBoxLayout

          QVBoxLayout是Qt中的一個布局管理器類,用于垂直方向排列小部件。它繼承自QLayout,提供了一種簡便的方式來自動管理窗口或對話框中小部件的位置和大小。使用QVBoxLayout,可以將小部件從上到下依次排列,而不需要手動指定每個小部件的具體位置。

          QVBoxLayout繼承關系圖

          簡單示例如下:

          import sys
          from PySide6.QtWidgets import *
          class MainWindow(QMainWindow):
              def __init__(self):
                  super(MainWindow, self).__init__()
                  self.setWindowTitle("QVBoxLayout之垂直布局")
                  self.setMinimumSize(400, 300)
                  layout=QVBoxLayout()
                  layout.addWidget(QPushButton("1"))
                  layout.addWidget(QPushButton("2"))
                  layout.addWidget(QPushButton("3"))
                  widget=QWidget()
                  widget.setLayout(layout)
                  self.setCentralWidget(widget)
          
          if __name__=='__main__':
              app=QApplication(sys.argv)
              window=MainWindow()
              window.show()
              app.exec()

          效果圖如下:

          QVBoxLayout示例效果圖

          QGridLayout

          QGridLayout是Qt中一個非常強大的布局管理器,它提供一種網格式布局,這種布局由行和列組成(類似table),每個小部件占據網格中的一個或多個單元格。QGridLayout提供了靈活的方式來創建復雜的用戶界面,使得小部件的布局可以精確控制,同時也能自動適應窗口大小的變化,主要特性有:

          • 行列管理:可以指定小部件應該放在網格的哪一行哪一列,甚至可以跨越多行多列。
          • 自動調整大小:當窗口大小改變時,QGridLayout會自動調整小部件的大小和位置,保持布局的整潔和一致性。
          • 最小寬度和拉伸因子:每列(或行)可以有一個最小寬度和一個拉伸因子,這決定了在可用空間中它們將如何分配額外的空間。
          • 間距和邊距:可以設置小部件之間的間距(spacing())和布局邊緣的邊距(內容邊距),以控制布局的外觀。

          QGridLayout繼承關系圖

          示例代碼如下:

          import sys
          from PySide6.QtWidgets import *
          class MainWindow(QMainWindow):
              def __init__(self):
                  super(MainWindow, self).__init__()
                  self.setWindowTitle("QGridLayout之網格布局")
                  self.setMinimumSize(400, 300)
                  layout=QGridLayout()
                  # 為窗口部件設置樣式表,添加邊框
                  self.setStyleSheet("QWidget { border: 2px solid black; }")
                  layout.addWidget(QLabel('第0行第0列'), 0, 0)
                  layout.addWidget(QLabel('第0行第1列'), 0, 1)
                  layout.addWidget(QLabel('第1行第0列'), 1, 0)
                  layout.addWidget(QLabel('第1行第1列'), 1, 1)
                  widget=QWidget()
                  widget.setLayout(layout)
                  self.setCentralWidget(widget)
          
          if __name__=='__main__':
              app=QApplication(sys.argv)
              window=MainWindow()
              window.show()
              app.exec()

          效果圖如下:

          QGridLayout示例效果圖

          QStackedLayout

          QStackedLayout是Qt中的一個布局管理器,它可以在相同的空間內堆疊多個小部件,但一次只顯示一個小部件。這種布局非常適合用于實現向導、選項卡和其他需要在多個頁面之間切換的界面。

          QStackedLayout繼承關系圖

          主要特性:

          • 堆疊小部件:在同一個布局空間內堆疊多個小部件。
          • 單一可見性:一次只有一個小部件可見。
          • 動態切換:可以編程方式動態切換當前可見的小部件

          常用方法技巧:indexOf()函數返回小部件在該列表中的索引??梢允褂胊ddWidget()函數添加小部件到列表末尾,或者使用insertWidget()函數在給定索引處插入。removeWidget()函數從布局中移除給定索引的小部件。可以使用count()函數獲取布局中包含的小部件數量。widget()函數返回給定索引位置的小部件。當前顯示在屏幕上的小部件的索引由currentIndex()給出,并且可以使用setCurrentIndex()進行更改。以類似的方式,可以使用currentWidget()函數檢索當前顯示的小部件,并使用setCurrentWidget()函數進行更改。每當布局中的當前小部件發生變化或從布局中移除小部件時,分別會發出currentChanged()和widgetRemoved()信號。

          示例代碼如下:

          import sys
          from PySide6.QtGui import QPalette, QColor
          from PySide6.QtWidgets import *
          class MainWindow(QMainWindow):
              def __init__(self):
                  super().__init__()
                  self.setWindowTitle("QStackedLayout之堆疊布局")
                  self.setMinimumSize(400, 300)
                  pagelayout=QVBoxLayout()
                  button_layout=QHBoxLayout()
                  self.stacklayout=QStackedLayout()
                  pagelayout.addLayout(button_layout)
                  pagelayout.addLayout(self.stacklayout)
                  btn=QPushButton("red")
                  btn.pressed.connect(self.activate_tab_1)
                  button_layout.addWidget(btn)
                  self.stacklayout.addWidget(Color("red"))
                  btn=QPushButton("green")
                  btn.pressed.connect(self.activate_tab_2)
                  button_layout.addWidget(btn)
                  self.stacklayout.addWidget(Color("green"))
                  btn=QPushButton("yellow")
                  btn.pressed.connect(self.activate_tab_3)
                  button_layout.addWidget(btn)
                  self.stacklayout.addWidget(Color("yellow"))
                  widget=QWidget()
                  widget.setLayout(pagelayout)
                  self.setCentralWidget(widget)
          
              def activate_tab_1(self):
                  self.stacklayout.setCurrentIndex(0)
          
              def activate_tab_2(self):
                  self.stacklayout.setCurrentIndex(1)
          
              def activate_tab_3(self):
                  self.stacklayout.setCurrentIndex(2)
          
          class Color(QWidget):
              def __init__(self, color):
                  super(Color, self).__init__()
                  self.setAutoFillBackground(True)
                  palette=self.palette()
                  palette.setColor(QPalette.Window, QColor(color))
                  self.setPalette(palette)
          
          if __name__=='__main__':
              app=QApplication(sys.argv)
              window=MainWindow()
              window.show()
              app.exec()

          效果圖如下:

          QStackedLayout示例效果圖


          混合布局

          使用QHBoxLayout、QVBoxLayout、QGridLayout、QStackedLayout這幾種布局組合使用,來控制界面的整體風格視角,制作精美的布局效果

          示例代碼如下:

          import sys
          from PySide6.QtWidgets import *
          
          class MainWindow(QMainWindow):
              def __init__(self):
                  super(MainWindow, self).__init__()
                  self.setWindowTitle("混合布局")
                  self.setMinimumSize(400, 300)
                  self.setStyleSheet("QLabel { border: 1px solid blue; }")
                  layout1=QHBoxLayout()
                  layout2=QVBoxLayout()
                  layout3=QVBoxLayout()
                  layout1.setContentsMargins(0,0,0,0)
                  layout1.setSpacing(20)
                  layout2.addWidget(QLabel('hbox1-QVBoxLayout1'))
                  layout2.addWidget(QLabel('hbox1-QVBoxLayout2'))
                  layout2.addWidget(QLabel('hbox1-QVBoxLayout3'))
                  layout1.addLayout(layout2)
                  layout1.addWidget(QLabel('hbox2'))
                  layout3.addWidget(QLabel('hbox2-QVBoxLayout1'))
                  layout3.addWidget(QLabel('hbox2-QVBoxLayout2'))
                  layout1.addLayout(layout3)
                  widget=QWidget()
                  widget.setLayout(layout1)
                  self.setCentralWidget(widget)
          
          if __name__=='__main__':
              app=QApplication(sys.argv)
              window=MainWindow()
              window.show()
              app.exec()

          效果圖如下:


          混合布局效果圖

          注意:QLayout邊框及樣式不能通過這種方式來設置樣式效果,需要指定Widget的樣式

          #無效果
          self.setStyleSheet("QHBoxLayout { border: 1px solid black; }")
          #有效果
          self.setStyleSheet("QLabel { border: 1px solid blue; }")

          自定義Layout,實現部件自動換行

          由于QHBoxLayout、QVBoxLayout、QGridLayout、QStackedLayout布局放置的控件,不增加任何處理,生成的控件會固定住窗口大小,可以通過下面來動態排列控件。

          示例代碼如下:

          import sys
          from PySide6.QtCore import QRect, QSize, QPoint, Qt
          from PySide6.QtWidgets import *
          
          class FlowLayout(QLayout):
              def __init__(self, parent=None, margin=0, spacing=-1):
                  super(FlowLayout, self).__init__(parent)
                  if parent is not None:
                      self.setContentsMargins(margin, margin, margin, margin)
                  self.setSpacing(spacing)
                  self.items=[]
          
              def addItem(self, item):
                  self.items.append(item)
          
              def count(self):
                  return len(self.items)
          
              def itemAt(self, index):
                  if index >=0 and index < len(self.items):
                      return self.items[index]
                  return None
          
              def takeAt(self, index):
                  if index >=0 and index < len(self.items):
                      return self.items.pop(index)
                  return None
          
              def expandingDirections(self):
                  return 0
          
              def hasHeightForWidth(self):
                  return True
          
              def heightForWidth(self, width):
                  height=self.doLayout(QRect(0, 0, width, 0), True)
                  return height
          
              def setGeometry(self, rect):
                  super(FlowLayout, self).setGeometry(rect)
                  self.doLayout(rect, False)
          
              def sizeHint(self):
                  return QSize(self.doLayout(QRect(0, 0, 10000, 0), True), 10000)
          
              def doLayout(self, rect, testOnly):
                  x=rect.x()
                  y=rect.y()
                  lineHeight=0
                  for item in self.items:
                      wid=item.widget()
                      spaceX=self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,Qt.Horizontal)
                      spaceY=self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,Qt.Vertical)
                      nextX=x + item.sizeHint().width() + spaceX
                      if nextX - spaceX > rect.right() and lineHeight > 0:
                          x=rect.x()
                          y=y + lineHeight + spaceY
                          nextX=x + item.sizeHint().width() + spaceX
                          lineHeight=0
                      if not testOnly:
                          item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))
                      x=nextX
                      lineHeight=max(lineHeight, item.sizeHint().height())
          
                  return y + lineHeight - rect.y()
          if __name__=='__main__':
              app=QApplication(sys.argv)
              mainWidget=QWidget()
              mainWidget.setMinimumSize(300, 200)
              layout=FlowLayout(mainWidget)
              for i in range(50):
                  layout.addWidget(QPushButton(f'Button {i}'))
              mainWidget.setLayout(layout)
              mainWidget.show()
              sys.exit(app.exec_())

          效果如下:

          自定義Layout效果圖

          在程序員開發軟件界面系統也都是有多種多樣,每種開發語言基本上都有一種或多種界面引擎如:C skin, Direct UI , 還有金山、迅雷等廠商的界面SDK。

          今天推薦一個輕量級、自由度高、使用方便的界面庫 Htmlayout/Sciter。HTMLayout是一個免費的開源界面庫(核心未開源),以DLL的方式運行,并提供一個API的調用接口和一系列的C++封裝和sample例程。HTMLayout: 快速,輕量、嵌入式的,基于HTML/CSS渲染技術和布局管理的界面引擎組件,可以高效地解析和渲染HTML網頁。其幾乎支持所有的HTML元素和CSS3標準,并根據界面庫的特征,做了很多有用的功能性擴展。

          界面預覽

          這里著重地說一下在 aardio 軟件中的使用,作者把 HTMLayout和 Sciter 制作成了擴展庫, 并且免費開源, 通過這個擴展庫你知道會一點點 HTML 和 CSS 知識就可以方便地制作各種漂亮的 ui。通過作者的努力你還可以直接在界面上使用現在最流行的字體圖標,還使擴展庫支持了模板功能,你可以像寫PHP一樣寫桌面軟件的界面HTML,雖然看起來簡單的代碼,但用起來會非常方便。

          效果圖

          效果圖

          言歸正傳, 我們用aardio一步步來制作一個最簡單的界面。

          1、打開軟件》新建工程》選擇web界面》選擇HTMLayout》創建工程

          字體圖標

          效果圖

          aardio 里查看 main.aardio 源碼

           import win.ui;
          /*DSG{{*/
          var winform=win.form(text="htmlayout";right=761;bottom=609;border="none")
          winform.add()
          /*}}*/
          
          import web.layout; 
          import web.layout.behavior.windowCommand;
          import web.layout.behavior.tabs;
          // 加載網頁
          var wbLayout=web.layout( winform );
          wbLayout.go("\layout\ui.html");
          
          if(_STUDIO_INVOKED){
          	import web.layout.debug;
          	wbLayout.attachEventHandler( web.layout.debug );
          } 
          
          //添加陰影邊框
          import win.ui.shadow;
          win.ui.shadow( winform,50,3 );
          
          winform.show() 
          win.loopMessage();

          從上面我們可以看出,軟件的主要界面是由 ui.html,ui.css,tabs.css 這幾個文件組成的。然后你可以根據自己軟件界面的需要進行調整。

          工程項目

          以下是我自己這二天搭建的一個軟件的界面,就是一個簡單的軟件基本框架。

          演示圖上

          工程項目目錄結構

          如果你對htmlayout感興趣,可以查看 https://bbs.aardio.com/forum.php?mod=forumdisplay&fid=128&page=1 了解更多更詳細的教程。


          主站蜘蛛池模板: 无码人妻精品一区二| 无码精品人妻一区二区三区漫画| 国产精品被窝福利一区 | 精品欧美一区二区在线观看 | 国产高清一区二区三区四区| 曰韩人妻无码一区二区三区综合部 | 精品国产日韩亚洲一区| 国产一区二区三区美女| 国产福利电影一区二区三区久久老子无码午夜伦不| 国产韩国精品一区二区三区久久| 78成人精品电影在线播放日韩精品电影一区亚洲 | 欧亚精品一区三区免费| 日韩在线视频一区二区三区 | 亚洲狠狠狠一区二区三区| 在线欧美精品一区二区三区| 久久精品国产AV一区二区三区| 国产福利91精品一区二区| 一区在线免费观看| 精品国产一区二区三区av片| 久久99国产精品一区二区| 无码午夜人妻一区二区不卡视频| 精品一区精品二区| 亚洲国产精品无码第一区二区三区| 国产一区二区三区在线| 精品性影院一区二区三区内射| 无码人妻一区二区三区精品视频| 亚洲乱码一区二区三区国产精品 | 无码人妻一区二区三区一| 最美女人体内射精一区二区| 在线精品视频一区二区| 日本成人一区二区三区| 中文字幕无码免费久久9一区9| 精品动漫一区二区无遮挡| 国产精品日本一区二区不卡视频| 丰满人妻一区二区三区视频53| 日韩中文字幕一区| 国产一区二区在线观看| 国内精品视频一区二区八戒| 亚洲av无码成人影院一区| 中文字幕无线码一区二区 | 国产一区二区三区不卡观|