跳到內容

譜面圖片

介面透過 Cassiopeia 靜態概覽 renderer 呈現已釋出譜面。Handler支援SVG和已註冊PNG rasterizer,PNG部署包含匹配Fontsource manifest/files;下方應用顯示實際公開Worker回應。

Terminal window
curl --fail-with-body \
'https://haneoka.org/api/v1/songs/100070/charts/expert/image.svg?server=intl&locale=en&height=720&download=1' \
-o chart.svg

把字尾換成 png 得到 PNG。顯式形式為 /api/v1/servers/{server}/songs/{songId}/charts/{difficulty}/image.{format}。兩者固定讀取當前資料,不接受 release。難度應來自歌曲 DTO 已公佈的 difficulty。

引數值含義
server活動 slug,alias 預設 intl資料伺服器
difficultyeasy/normal/hard/expert/special/master路徑引數,歌曲必須提供該難度
localeja/en/zh-TW/zh-CN/ko圖中文字,省略時協商 Accept-Language
height360–1440 整數,預設720單個譜面段高度,不含頁首
download1/0,預設1attachment 或 inline
formatsvg/png檔案字尾與 MIME

重複或空引數返回400。輸入和輸出受渲染預算約束,超預算返回413。

最終圖片包含頁首和整曲所需段數;提高段高會影響段數及最終寬度。以 X-Haneoka-Image-Width/Height 為圖片佔位尺寸,與 SVG width/height 或 PNG IHDR 一致。height query 不是最終畫布高度。

回應還包含 Content-Type、Content-Length、Content-Disposition、Content-Language、ETag、X-Haneoka-Server/Release-Id/Chart-Renderer。GET 返回圖片,HEAD 只返回頭,If-None-Match 可得到304且不帶 Content-Length。公開端點支援匿名 CORS、OPTIONS204 和不支援方法的405/Allow。

const url = "https://haneoka.org/api/v1/songs/100070/charts/expert/image.png?locale=en&download=0";
const response = await fetch(url, { credentials: "omit" });
if (!response.ok) {
const failure = await response.json();
throw new Error(`${response.status}: ${failure.error.code}`);
}
const width = Number(response.headers.get("X-Haneoka-Image-Width"));
const height = Number(response.headers.get("X-Haneoka-Image-Height"));
const imageUrl = URL.createObjectURL(await response.blob());
console.log(width, height, imageUrl);
// 給 img 設定寬高與 src,解除安裝時 URL.revokeObjectURL(imageUrl)。

錯誤為 error.code/message/requestId,帶 X-Request-Id 和 no-store。引數錯誤400,歌曲/難度/譜面缺失404,格式406,輸入/渲染預算413,光柵失敗502,當前釋出不可用503。具體 code 見 OpenAPI。PNG 字型缺失或無效為 chart_image_failed,字型預算超限為 chart_render_budget;未接 rasterizer 的部署可返回501 png_renderer_unavailable。保留 requestId,根據引數或部署原因修復後重試。

修改server/song/difficulty/format/locale/段高/download,選擇GET/HEAD/OPTIONS。點選才請求真實端點,成功GET按真實尺寸預覽並下載同一回應bytes;錯誤顯示真實status/body,不用本地圖片替代不可用服務。

修改 JSON 再發送請求。回應顯示實際狀態、尺寸與快取標頭;GET 成功後預覽圖片並提供原回應下載。

語言

正在準備範例…

檢視範例程式碼

scoped選顯式server路徑,apiBase為相容API,acceptLanguage/ifNoneMatch為header;ifNoneMatch:$last使用上一ETag,這些是應用transport欄位。HEAD/OPTIONS/304無新圖正文,正式cache應複用舊錶示,檢查器顯示頭。清理/替換/退出revoke BlobURL,不import GPU/SDK或預載入圖片。

GET/HEAD alias /api/v1/songs/{songId}/charts/{difficulty}/image.{format},可選server;或 /api/v1/servers/{server}/songs/{songId}/charts/{difficulty}/image.{format}。公開無需帳號;OPTIONS先204,不讀源,其他方法405/Allow。

引數必填/預設校驗/作用
songId必填string路徑1–256位,首字母數字,其餘可 . _ : ~ -,單段編碼;非法/缺404 song_not_found。
difficulty必填小寫路徑easy/normal/hard/expert/special/master且DTO有,缺404 difficulty_not_found。
format必填字尾svg/png小寫;匹配但不支援的小寫字尾406,壞route可404。
serverscoped必填,alias intl活動1–40位小寫字母數字/連字元,首尾字母數字。alias重複400 invalid_server,壞/未知404;scopedquery需匹配path。
locale可選,協商ja/en/zh-TW/zh-CN/ko,空/重複/不支援400 invalid_locale,與server獨立。
height可選7201–4位十進位制整數360–1440,空/小數/越界/重複400 invalid_height;單段不含header。
download可選1僅0/1一次,inline/attachment,空/其它/重複400 invalid_download。
release不支援任何值400 release_not_supported,current讀取。

沒有width/title/band/noteSpeed/jacket覆蓋引數,來自實際song/score。query大小寫精確;非空body400 body_not_allowed。

header方向/預設作用
Accept-Language可選request無locale時BCP47協商。
If-None-Match可選request強/弱etag或*匹配304,無Content-Length。
Content-TyperesponseSVGUTF8/PNG,錯誤JSON。
Content-Length200/HEAD真實編碼bytes,304無。
Content-Dispositionresponse預設attachment或inline,檔名含server/song/difficulty/locale。
Content-Languageresponse選定語言。
ETagresponse表示bytes+server/release/song/locale/renderer identity。
X-Haneoka-Serverresponseregistry。
X-Haneoka-Release-Idresponse真實current版本。
X-Haneoka-Chart-Rendererresponserenderer版本。
X-Haneoka-Image-Width/Heightresponse含header/panels的最終畫布。
Cache-Controlsuccess public/max-age300/must-revalidate錯誤no-store。
VaryAccept-Language協商快取。
X-Request-Iddispatcher錯誤body也有requestId。
Allow405GET/HEAD/OPTIONS。

匿名CORS origin*,允許上述方法和Content-Type/Accept/Accept-Language/If-None-Match;暴露Disposition/Length、renderer/release/server/尺寸/ETag。瀏覽器只讀允許暴露的頭,header讀不到時保留錯誤body.requestId。HEAD無正文,Range不是圖片API欄位,讀取全圖或ETag複驗。

chart2MiB、可選jacket1MiB;缺/不支援jacket可省略仍渲染。最多256panels、12000000pixels、SVG8MiB;PNG驗證signature/IHDR/尺寸及8MiB。預算不是query開關,PNG部署包括rasterizer和Fontsource manifest/files。

status/code原因恢復
400 invalid_height/locale/download/server壞/空/重複改引數。
400 release_not_supported/body_not_allowedrelease/bodycurrent無body讀取。
404 server/song/difficulty/chart_not_found無可用源從catalog選已有。
405 method_not_allowed非readGET/HEAD/OPTIONS。
406 format_not_supported匹配但不支援字尾svg/png。
413 chart_too_large/chart_render_budgetinput/font/output預算選較小可用譜面/報告,不同參重複超限無效。
501 png_renderer_unavailable未部署PNG器SVG或部署。
502 chart_path_invalid/chart_invalid/release_invalid壞identity/path/score保留requestId報告。
502 png_invalid/chart_image_failedsignature/尺寸/font失敗修部署/字型。
503 release_unavailable無current有界backoff重試。

公開dispatcher error為code/message/requestId,帶X-Request-Id/no-store。fetch/CORS/abort在此envelope之前,獨立展示。是否上線以實際Worker回應為準,頁面示例記錄它,不把docs部署當API部署。