Open ChrisJAllan opened 1 year ago
I have a working build that just copies the texture-reading code from HTTP Status, but I don't think it's pull-request-worthy.
diff --git a/src/Core/MapEvents.cs b/src/Core/MapEvents.cs index 4dbbc91..55fa3db 100644 --- a/src/Core/MapEvents.cs +++ b/src/Core/MapEvents.cs @@ -178,7 +178,7 @@ namespace DataPuller.Core MapData.Instance.Send(); } - public void LevelLoaded() + public async void LevelLoaded() { PlayerData playerData = Resources.FindObjectsOfTypeAll<PlayerDataModel>().FirstOrDefault().playerData; IBeatmapLevel levelData = gameplayCoreSceneSetupData.difficultyBeatmap.level; @@ -204,6 +204,40 @@ namespace DataPuller.Core MapData.Instance.Difficulty = gameplayCoreSceneSetupData.difficultyBeatmap.difficulty.ToString("g"); MapData.Instance.NJS = gameplayCoreSceneSetupData.difficultyBeatmap.noteJumpMovementSpeed; MapData.Instance.CustomDifficultyLabel = difficultyData?._difficultyLabel ?? null; + + // From HTTPStatus + try { + // From https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures- + // Modified to correctly handle texture atlases. Fixes #82. + var active = RenderTexture.active; + + var sprite = await levelData.GetCoverImageAsync(System.Threading.CancellationToken.None); + var texture = sprite.texture; + var temporary = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); + + Graphics.Blit(texture, temporary); + RenderTexture.active = temporary; + + var spriteRect = sprite.rect; + var uv = sprite.uv[0]; + + var cover = new Texture2D((int) spriteRect.width, (int) spriteRect.height); + // Unity sucks. The coordinates of the sprite on its texture atlas are only accessible through the Sprite.uv property since rect always returns `x=0,y=0`, so we need to convert them back into texture space. + cover.ReadPixels(new Rect( + uv.x * texture.width, + texture.height - uv.y * texture.height, + spriteRect.width, + spriteRect.height + ), 0, 0); + cover.Apply(); + + RenderTexture.active = active; + RenderTexture.ReleaseTemporary(temporary); + + MapData.Instance.CoverImage = "data:image/png;base64," + System.Convert.ToBase64String(ImageConversion.EncodeToPNG(cover)); + } catch { + MapData.Instance.CoverImage = null; + } if (isCustomLevel) { @@ -267,7 +301,6 @@ namespace DataPuller.Core else { MapData.Instance.BSRKey = null; - MapData.Instance.CoverImage = null; } MapData.Instance.Send(); });
For what it's worth, I have fixed this as of v2.1.11 in my fork using your solution as a base
I have a working build that just copies the texture-reading code from HTTP Status, but I don't think it's pull-request-worthy.