Raspberry Pi 4 (Raspberry Pi OS 64bit)で、ディスプレイ(モニタ)を接続せずにVNCでヘッドレス運用時、ディスプレイ解像度(画面サイズ)を変える方法

インターネット上の記事をRaspberry Piを主眼に検索すると、設定方法の歴史的な変遷で、いくつかの方法が見つかりますが、うまくいきませんでした。
結果的には、LinuxのX Window Systemベースの以前から使われていたコマンドで変更できましたので、記載しておきます。

```change_resolution_1920x1600.sh
#!/bin/sh
xrandr --newmode  "1920x1600_60.00"  260.75  1920 2064 2272 2624  1600 1603 1613
 1658 -hsync +vsync
xrandr --addmode HDMI-1 1920x1600_60.00
xrandr --output HDMI-1 --mode 1920x1600_60.00
```

# 変更方法

上記のシェルスクリプトのように、xrandrコマンドを使えば、解像度を変更できます。
ただし、コマンドライン引数は適当ではなく、cvtコマンドを使って調べた結果を使っています。

また、上記の例では、VNCで接続後に当該DISPLAYに対して変更しています。（必要な時だけ必要な解像度に変更したかったため）

# 変更手順

## 0. 現在認識されているディスプレイとモードを確認する

```shell
pi@raspberrypi:~ $ xrandr
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 7680 x 7680
HDMI-1 disconnected primary (normal left inverted right x axis y axis)
HDMI-2 disconnected (normal left inverted right x axis y axis)
pi@raspberrypi:~ $ 
```

上記の例は、2つのHDMIコネクタには何も接続せず、VNCでリモート接続した時の様子です。（どのモードも認識されていません）
なお、OSインストール時は、HDMI-1に物理モニタを接続して、試行錯誤していました。

## 1. cvtコマンドでnewmode指定方法を確認する

```shell
pi@raspberrypi:~ $ cvt 1920 1080
# 1920x1080 59.96 Hz (CVT 2.07M9) hsync: 67.16 kHz; pclk: 173.00 MHz
Modeline "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
pi@raspberrypi:~ $ 
```

`cvt`の後に、変更したい解像度の数値を引数として指定して実行すると、xrandrコマンドの--addmodeオプションで使用できる文字列が出力されます。

## 2. xrandrコマンドでモードを追加する

```shell
pi@raspberrypi:~ $ xrandr --newmode "1920x1080_60.00"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
pi@raspberrypi:~ $ 
```

`xrandr --newmode`の後に、cvtコマンドの出力の「Modeline」より後の部分をコピペして実行します。

## 3. 追加したモードを確認する

```shell
pi@raspberrypi:~ $ xrandr
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 7680 x 7680
HDMI-1 disconnected primary (normal left inverted right x axis y axis)
HDMI-2 disconnected (normal left inverted right x axis y axis)
  1920x1080_60.00 (0x367) 173.000MHz -HSync +VSync
        h: width  1920 start 2048 end 2248 total 2576 skew    0 clock  67.16KHz
        v: height 1080 start 1083 end 1088 total 1120           clock  59.96Hz
pi@raspberrypi:~ $ 
```

モードが追加されていることが確認できます。

## 4. xrandrコマンドで追加したモードをディスプレイに割り当てる

```shell
pi@raspberrypi:~ $ xrandr --addmode HDMI-1 1920x1080_60.00
pi@raspberrypi:~ $ 
```

## 5. 割り当てたモードを確認する

```shell
pi@raspberrypi:~ $ xrandr
Screen 0: minimum 320 x 200, current 1024 x 768, maximum 7680 x 7680
HDMI-1 disconnected primary (normal left inverted right x axis y axis)
   1920x1080_60.00  59.96  
HDMI-2 disconnected (normal left inverted right x axis y axis)
pi@raspberrypi:~ $ 
```

HDMI-1に割り当てられていることが確認できます。

## 6. xrandrコマンドでモードを変更する

```shell
pi@raspberrypi:~ $ xrandr --output HDMI-1 --mode 1920x1080_60.00
pi@raspberrypi:~ $ 
```

VNCで接続している場合、このコマンドを実行したタイミングで、画面サイズが変わります。

## 7. 必要に応じ、自動実行できるようにする

冒頭のシェルスクリプトの例のように、一連の手順を実行できるようにしておき、必要に応じて自動実行するようにしておくと便利かもしれません。

# インターネット上の記事を検索して、うまくいかなかった方法

* GUI起動後の設定メニュー内の「Screen Configuration」を使う方法
* raspi-configを使う方法（GUI版でも、CUI版でも設定項目がなくなっています）
* /boot/config.txtでhdmi_groupとhdmi_modeを直接記述して設定する方法
* raspi-config nonint do_resolutionで非対話で設定する方法（コマンドは成功するも、前項がダメなので）
* /boot/config.txtでhdmi_ignore_edid=0xa5000080を指定する方法
* /boot/config.txtでframebuffer_widthとframebuffer_heightをコメントアウトして設定する方法
* /opt/vc/bin/tvserviceを使う方法

# 環境

* 2021年6月時点
* Raspberry Pi 4 (8GB)
* Raspberry Pi OS Buster 64bit (http://downloads.raspberrypi.org/raspios_arm64/images/raspios_arm64-2021-04-09/2021-03-04-raspios-buster-arm64.zip)
* OSはapt full-upgradeした状態