yocker 1247 Posted July 26, 2025 Author Posted July 26, 2025 (edited) @sh0rty I removed the bit in the code that disabled the thumbs and banners. Problem now (i think) is that with that simple change the icons get shown on the continue watching as well. Is that something you would think should stay or shall they be removed from that is possible? I ask because you made the request so up to you. Edit: Actually never mind all that, doesn't seem like there would be a way to not have it on the continue watching as well. At any rate, just need to add a way to enable and disable it to the settings and such, will take a day or two and you should have banner and thumb support. Edited July 26, 2025 by yocker 1
sh0rty 714 Posted July 26, 2025 Posted July 26, 2025 (edited) 1 hour ago, yocker said: @sh0rty I removed the bit in the code that disabled the thumbs and banners. Problem now (i think) is that with that simple change the icons get shown on the continue watching as well. Is that something you would think should stay or shall they be removed from that is possible? I ask because you made the request so up to you. Edit: Actually never mind all that, doesn't seem like there would be a way to not have it on the continue watching as well. At any rate, just need to add a way to enable and disable it to the settings and such, will take a day or two and you should have banner and thumb support. Don't see a problem in having it also inside the continue watching thumbs. Actually I find it very useful and stringent. Thanks for your work! Edited July 26, 2025 by sh0rty 1
keitaro26 22 Posted July 26, 2025 Posted July 26, 2025 9 minutes ago, sh0rty said: Don't see a problem in having it also inside the continue wachting thumbs. Actually I find it very useful and stringent. Thanks for your work! Agreed, having it in the continue watching would actually be helpful for me
yocker 1247 Posted July 26, 2025 Author Posted July 26, 2025 Good thing then that it wouldn't be possible to disable it! It will be in the next version, shouldn't take long.
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 @sh0rty @keitaro26 Try this, i removed the code preventing drawing on thumbs and banners plus made some settings for it. EmbyIcons.dll 2
bakes82 167 Posted July 27, 2025 Posted July 27, 2025 On 7/22/2025 at 12:13 PM, yocker said: Sadly not something i can fix (at least can't think of a way). Not much space to work on with a poster. Does this fix the issue? I ran it thru claude code and told it to allow it to overflow and set a max row count of 2 (you can figure out if you want to let users customize) private SKSize DrawIconGroup(SKCanvas canvas, OverlayGroupInfo group, int size, int edgePadding, int interIconPadding, int width, int height, SKPaint paint, int verticalOffset, int horizontalOffset) { bool isRight = group.Alignment == IconAlignment.TopRight || group.Alignment == IconAlignment.BottomRight; bool isBottom = group.Alignment == IconAlignment.BottomLeft || group.Alignment == IconAlignment.BottomRight; int GetIconWidth(SKImage i) => i.Height > 0 ? (int)Math.Round(size * ((float)i.Width / i.Height)) : size; if (!group.HorizontalLayout) { // Vertical layout with column wrapping var availableHeight = height - (2 * edgePadding) - verticalOffset; var iconWidths = group.Icons.Select(GetIconWidth).ToList(); // Calculate layout - determine which icons go in which column const int maxColumns = 2; // Limit to 2 columns maximum var columns = new List<List<int>>(); // List of columns, each containing icon indices var currentColumn = new List<int>(); var currentColumnHeight = 0; for (int i = 0; i < group.Icons.Count; i++) { var requiredHeight = size + (currentColumn.Count > 0 ? interIconPadding : 0); if (currentColumn.Count == 0 || currentColumnHeight + requiredHeight <= availableHeight) { // Icon fits in current column currentColumn.Add(i); currentColumnHeight += requiredHeight; } else { // Start new column, but only if we haven't reached the max if (currentColumn.Count > 0) { columns.Add(currentColumn); } if (columns.Count >= maxColumns) { // Already at max columns, stop adding more icons break; } currentColumn = new List<int> { i }; currentColumnHeight = size; } } if (currentColumn.Count > 0 && columns.Count < maxColumns) { columns.Add(currentColumn); } // Calculate total dimensions var maxColumnWidth = columns.Select(col => col.Select(idx => iconWidths[idx]).DefaultIfEmpty(0).Max() ).DefaultIfEmpty(0).Max(); var totalWidth = columns.Count * maxColumnWidth + (columns.Count - 1) * interIconPadding; var maxColumnHeight = columns.Select(col => col.Count * size + (col.Count - 1) * interIconPadding ).DefaultIfEmpty(0).Max(); // Draw icons column by column for (int columnIndex = 0; columnIndex < columns.Count; columnIndex++) { var column = columns[columnIndex]; var columnHeight = column.Count * size + (column.Count - 1) * interIconPadding; // Calculate X position for this column float currentX; if (isRight) { // Right alignment: first column at right, subsequent columns go leftward // Column 0 (first icons) is at the right, Column 1 goes to the left of it, etc. currentX = width - maxColumnWidth - edgePadding - horizontalOffset - (columnIndex * (maxColumnWidth + interIconPadding)); } else { // Left alignment: position columns rightward from the left currentX = edgePadding + horizontalOffset + (columnIndex * (maxColumnWidth + interIconPadding)); } // Calculate Y starting position for this column float columnStartY; if (isBottom) { columnStartY = height - columnHeight - edgePadding - verticalOffset; } else { columnStartY = edgePadding + verticalOffset; } float currentY = columnStartY; foreach (var iconIndex in column) { var img = group.Icons[iconIndex]; var iconWidth = iconWidths[iconIndex]; var iconHeight = size; canvas.DrawImage(img, new SKRect(currentX, currentY, currentX + iconWidth, currentY + iconHeight), paint); currentY += iconHeight + interIconPadding; } } return new SKSize(totalWidth, maxColumnHeight); } else { // Horizontal layout with wrapping var availableWidth = width - (2 * edgePadding) - horizontalOffset; var iconWidths = group.Icons.Select(GetIconWidth).ToList(); // Calculate layout - determine which icons go on which row const int maxRows = 2; // Limit to 2 rows maximum var rows = new List<List<int>>(); // List of rows, each containing icon indices var currentRow = new List<int>(); var currentRowWidth = 0; for (int i = 0; i < group.Icons.Count; i++) { var iconWidth = iconWidths[i]; var requiredWidth = iconWidth + (currentRow.Count > 0 ? interIconPadding : 0); if (currentRow.Count == 0 || currentRowWidth + requiredWidth <= availableWidth) { // Icon fits in current row currentRow.Add(i); currentRowWidth += requiredWidth; } else { // Start new row, but only if we haven't reached the max if (currentRow.Count > 0) { rows.Add(currentRow); } if (rows.Count >= maxRows) { // Already at max rows, stop adding more icons break; } currentRow = new List<int> { i }; currentRowWidth = iconWidth; } } if (currentRow.Count > 0 && rows.Count < maxRows) { rows.Add(currentRow); } // Calculate total dimensions var maxRowWidth = rows.Select(row => row.Sum(idx => iconWidths[idx]) + (row.Count - 1) * interIconPadding ).DefaultIfEmpty(0).Max(); var totalHeight = rows.Count * size + (rows.Count - 1) * interIconPadding; // Calculate starting position float startX = isRight ? width - maxRowWidth - edgePadding - horizontalOffset : edgePadding + horizontalOffset; // Draw icons row by row for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++) { var row = rows[rowIndex]; var rowWidth = row.Sum(idx => iconWidths[idx]) + (row.Count - 1) * interIconPadding; float rowStartX = isRight ? startX + (maxRowWidth - rowWidth) : startX; // Calculate Y position for this row float currentY; if (isBottom) { // Bottom alignment: first row at bottom, subsequent rows go upward // Row 0 (first icons) is at the bottom, Row 1 goes above it, etc. currentY = height - size - edgePadding - verticalOffset - (rowIndex * (size + interIconPadding)); } else { // Top alignment: position rows downward from the top currentY = edgePadding + verticalOffset + (rowIndex * (size + interIconPadding)); } float currentX = rowStartX; foreach (var iconIndex in row) { var img = group.Icons[iconIndex]; var iconWidth = iconWidths[iconIndex]; var iconHeight = size; canvas.DrawImage(img, new SKRect(currentX, currentY, currentX + iconWidth, currentY + iconHeight), paint); currentX += iconWidth + interIconPadding; } } return new SKSize(maxRowWidth, totalHeight); } }
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 32 minutes ago, bakes82 said: Does this fix the issue? I ran it thru claude code and told it to allow it to overflow and set a max row count of 2 (you can figure out if you want to let users customize) private SKSize DrawIconGroup(SKCanvas canvas, OverlayGroupInfo group, int size, int edgePadding, int interIconPadding, int width, int height, SKPaint paint, int verticalOffset, int horizontalOffset) { bool isRight = group.Alignment == IconAlignment.TopRight || group.Alignment == IconAlignment.BottomRight; bool isBottom = group.Alignment == IconAlignment.BottomLeft || group.Alignment == IconAlignment.BottomRight; int GetIconWidth(SKImage i) => i.Height > 0 ? (int)Math.Round(size * ((float)i.Width / i.Height)) : size; if (!group.HorizontalLayout) { // Vertical layout with column wrapping var availableHeight = height - (2 * edgePadding) - verticalOffset; var iconWidths = group.Icons.Select(GetIconWidth).ToList(); // Calculate layout - determine which icons go in which column const int maxColumns = 2; // Limit to 2 columns maximum var columns = new List<List<int>>(); // List of columns, each containing icon indices var currentColumn = new List<int>(); var currentColumnHeight = 0; for (int i = 0; i < group.Icons.Count; i++) { var requiredHeight = size + (currentColumn.Count > 0 ? interIconPadding : 0); if (currentColumn.Count == 0 || currentColumnHeight + requiredHeight <= availableHeight) { // Icon fits in current column currentColumn.Add(i); currentColumnHeight += requiredHeight; } else { // Start new column, but only if we haven't reached the max if (currentColumn.Count > 0) { columns.Add(currentColumn); } if (columns.Count >= maxColumns) { // Already at max columns, stop adding more icons break; } currentColumn = new List<int> { i }; currentColumnHeight = size; } } if (currentColumn.Count > 0 && columns.Count < maxColumns) { columns.Add(currentColumn); } // Calculate total dimensions var maxColumnWidth = columns.Select(col => col.Select(idx => iconWidths[idx]).DefaultIfEmpty(0).Max() ).DefaultIfEmpty(0).Max(); var totalWidth = columns.Count * maxColumnWidth + (columns.Count - 1) * interIconPadding; var maxColumnHeight = columns.Select(col => col.Count * size + (col.Count - 1) * interIconPadding ).DefaultIfEmpty(0).Max(); // Draw icons column by column for (int columnIndex = 0; columnIndex < columns.Count; columnIndex++) { var column = columns[columnIndex]; var columnHeight = column.Count * size + (column.Count - 1) * interIconPadding; // Calculate X position for this column float currentX; if (isRight) { // Right alignment: first column at right, subsequent columns go leftward // Column 0 (first icons) is at the right, Column 1 goes to the left of it, etc. currentX = width - maxColumnWidth - edgePadding - horizontalOffset - (columnIndex * (maxColumnWidth + interIconPadding)); } else { // Left alignment: position columns rightward from the left currentX = edgePadding + horizontalOffset + (columnIndex * (maxColumnWidth + interIconPadding)); } // Calculate Y starting position for this column float columnStartY; if (isBottom) { columnStartY = height - columnHeight - edgePadding - verticalOffset; } else { columnStartY = edgePadding + verticalOffset; } float currentY = columnStartY; foreach (var iconIndex in column) { var img = group.Icons[iconIndex]; var iconWidth = iconWidths[iconIndex]; var iconHeight = size; canvas.DrawImage(img, new SKRect(currentX, currentY, currentX + iconWidth, currentY + iconHeight), paint); currentY += iconHeight + interIconPadding; } } return new SKSize(totalWidth, maxColumnHeight); } else { // Horizontal layout with wrapping var availableWidth = width - (2 * edgePadding) - horizontalOffset; var iconWidths = group.Icons.Select(GetIconWidth).ToList(); // Calculate layout - determine which icons go on which row const int maxRows = 2; // Limit to 2 rows maximum var rows = new List<List<int>>(); // List of rows, each containing icon indices var currentRow = new List<int>(); var currentRowWidth = 0; for (int i = 0; i < group.Icons.Count; i++) { var iconWidth = iconWidths[i]; var requiredWidth = iconWidth + (currentRow.Count > 0 ? interIconPadding : 0); if (currentRow.Count == 0 || currentRowWidth + requiredWidth <= availableWidth) { // Icon fits in current row currentRow.Add(i); currentRowWidth += requiredWidth; } else { // Start new row, but only if we haven't reached the max if (currentRow.Count > 0) { rows.Add(currentRow); } if (rows.Count >= maxRows) { // Already at max rows, stop adding more icons break; } currentRow = new List<int> { i }; currentRowWidth = iconWidth; } } if (currentRow.Count > 0 && rows.Count < maxRows) { rows.Add(currentRow); } // Calculate total dimensions var maxRowWidth = rows.Select(row => row.Sum(idx => iconWidths[idx]) + (row.Count - 1) * interIconPadding ).DefaultIfEmpty(0).Max(); var totalHeight = rows.Count * size + (rows.Count - 1) * interIconPadding; // Calculate starting position float startX = isRight ? width - maxRowWidth - edgePadding - horizontalOffset : edgePadding + horizontalOffset; // Draw icons row by row for (int rowIndex = 0; rowIndex < rows.Count; rowIndex++) { var row = rows[rowIndex]; var rowWidth = row.Sum(idx => iconWidths[idx]) + (row.Count - 1) * interIconPadding; float rowStartX = isRight ? startX + (maxRowWidth - rowWidth) : startX; // Calculate Y position for this row float currentY; if (isBottom) { // Bottom alignment: first row at bottom, subsequent rows go upward // Row 0 (first icons) is at the bottom, Row 1 goes above it, etc. currentY = height - size - edgePadding - verticalOffset - (rowIndex * (size + interIconPadding)); } else { // Top alignment: position rows downward from the top currentY = edgePadding + verticalOffset + (rowIndex * (size + interIconPadding)); } float currentX = rowStartX; foreach (var iconIndex in row) { var img = group.Icons[iconIndex]; var iconWidth = iconWidths[iconIndex]; var iconHeight = size; canvas.DrawImage(img, new SKRect(currentX, currentY, currentX + iconWidth, currentY + iconHeight), paint); currentX += iconWidth + interIconPadding; } } return new SKSize(maxRowWidth, totalHeight); } } It's a good ide, Making overflow to another line and then direct the flow of those line based on corner setting for the icons might work. Many thanks, will look into it!
sh0rty 714 Posted July 27, 2025 Posted July 27, 2025 (edited) 7 hours ago, yocker said: @sh0rty @keitaro26 Try this, i removed the code preventing drawing on thumbs and banners plus made some settings for it. EmbyIcons.dll 3.25 MB · 2 downloads Works like a charm. Thanks you so much! It just does not work for season posters, e.g. when all the season episodes have DV, the season should also have the DV tag. But I don't know if that's an Emby limitation. Edited July 27, 2025 by sh0rty 1
ISeeTWizard 29 Posted July 27, 2025 Posted July 27, 2025 11 hours ago, yocker said: @sh0rty @keitaro26 Try this, i removed the code preventing drawing on thumbs and banners plus made some settings for it. EmbyIcons.dll 3.25 MB · 2 downloads Doesn't seem to work for me but maybe I misunderstand something. I thought that also on the main page with the libraries listed the small images would get back the icons like it was before you rewrote the plugin? But just for my knowing: A simple activating for thumbs and poster in the settings should be enough? And maybe a clear cache? Nothing else is needed?
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 5 hours ago, sh0rty said: Works like a charm. Thanks you so much! It just does not work for season posters, e.g. when all the season episodes have DV, the season should also have the DV tag. But I don't know if that's an Emby limitation. I've been banging my head against the wall with this problem since you wrote it. Seems that there is a bug in Visual Studio or something that makes it so some names gets rejected when being embedded. I found a fix though and will apply it shortly. 1
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 44 minutes ago, ISeeTWizard said: Doesn't seem to work for me but maybe I misunderstand something. I thought that also on the main page with the libraries listed the small images would get back the icons like it was before you rewrote the plugin? But just for my knowing: A simple activating for thumbs and poster in the settings should be enough? And maybe a clear cache? Nothing else is needed? It never drew icons on the library folders them self. Sorry if i have misunderstood your message. 1
ISeeTWizard 29 Posted July 27, 2025 Posted July 27, 2025 6 minutes ago, yocker said: It never drew icons on the library folders them self. Sorry if i have misunderstood your message. Hmm not the library folder but the small thumbnails of the movies you see had icons before or maybe I have something wrong in my mind as before I used ratingposterdb I did a lot of changes so I can‘t remember them all lol I‘m getting old
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 18 minutes ago, ISeeTWizard said: Hmm not the library folder but the small thumbnails of the movies you see had icons before or maybe I have something wrong in my mind as before I used ratingposterdb I did a lot of changes so I can‘t remember them all lol I‘m getting old I think i understand you now. No, they didn't have icons in them unless there was a bug at some point, besides they would have been too small to see. 1
ISeeTWizard 29 Posted July 27, 2025 Posted July 27, 2025 Just now, yocker said: I think i understand you now. No, they didn't have icons in them unless there was a bug at some point, besides they would have been too small to see. Ok so it must have been those from the ratingposterdb as here the poster are completely replaced thanks 1
sh0rty 714 Posted July 27, 2025 Posted July 27, 2025 2 hours ago, yocker said: @sh0rty Try this one. EmbyIcons.dll 3.26 MB · 0 downloads That did not seem to work (all episodes from the example season are with DV).
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 (edited) 40 minutes ago, sh0rty said: That did not seem to work (all episodes from the example season are with DV). Hmm should work. Maybe Visual Studio is acting up.. Try this one, works for me. Remember to press the clear icon cache button after installing to clear the stale icons after a reboot of server. Just in case: Remember to also make a profile. EmbyIcons.dll Edited July 27, 2025 by yocker 1
yocker 1247 Posted July 27, 2025 Author Posted July 27, 2025 (edited) On 5/21/2025 at 2:30 PM, Neminem said: Is there any way of excluding extra folders, as I don't have subs for all the extras. So that only season 1 - xx is used, when creating flags for tv show poster. I would guess this is not easy to do Missed you post, sorry. While it would be technically possible to do, lite mode for example only scans the first episode, it would be very complex to make it so that only one series gets 4 seasons scanned. Maybe a setting for a global amount of seasons to scan but personally i don't really see the reason for that as i made it like it like it is so people needing the subtitles don't get stuck half way through a series. Edited July 27, 2025 by yocker 1
yocker 1247 Posted July 28, 2025 Author Posted July 28, 2025 @bakes82 I've been working on your idea. I changed the drawing logic to be more one by one basis instead of being groups, changed how corner behaves a little, made the community rating count for two different icons to make it not mess with the drawing lines and last made it allow for overflow. While it took some extra work your idea was a good one, thank you! ----- Warning to anyone wanting to try, this is VERY much a beta as i have only tested if the overlays are as they should be. No stability testing have been done yet!! EmbyIcons.dll
sh0rty 714 Posted July 28, 2025 Posted July 28, 2025 14 hours ago, yocker said: Hmm should work. Maybe Visual Studio is acting up.. Try this one, works for me. Remember to press the clear icon cache button after installing to clear the stale icons after a reboot of server. Just in case: Remember to also make a profile. EmbyIcons.dll 3.26 MB · 1 download Don't know what's wrong. It does not work on my side. But no problem, I made a separate profile for TV shows and set up my DV icon as tag for them.
yocker 1247 Posted July 28, 2025 Author Posted July 28, 2025 30 minutes ago, sh0rty said: Don't know what's wrong. It does not work on my side. But no problem, I made a separate profile for TV shows and set up my DV icon as tag for them. Have you set it to built in or custom icons? Well send you a new version when I get home where I'm making 100% sure visual studio haven't used a cached version
ISeeTWizard 29 Posted July 28, 2025 Posted July 28, 2025 Hey - I have a question I already had: parental ratings Now that you have it all dynamically generated wouldn't it be possible to add this too? So people simply can create their own icons for the ages? Thanks to the mapper plugin they can map all to just some possibilities to avoid having 3289412456192459 icons ? Before when it was hardcoded of course it would have been much to much work as every country has his own system but now dynamically? I'm not a developer so I don't know how what is possible or what not with your new version
yocker 1247 Posted July 28, 2025 Author Posted July 28, 2025 @sh0rty I made sure this version is not compiled with stuff that visual studio cached. Also can you give me a screen shot of one of your DV files? EmbyIcons.dll
yocker 1247 Posted July 28, 2025 Author Posted July 28, 2025 17 minutes ago, ISeeTWizard said: Hey - I have a question I already had: parental ratings Now that you have it all dynamically generated wouldn't it be possible to add this too? So people simply can create their own icons for the ages? Thanks to the mapper plugin they can map all to just some possibilities to avoid having 3289412456192459 icons ? Before when it was hardcoded of course it would have been much to much work as every country has his own system but now dynamically? I'm not a developer so I don't know how what is possible or what not with your new version I's not so much if it's dynamic or not, they still use each their own detection as they have to know where to look. It has ofc. made it easier. I will look into it after i'm done with the icon overflow. As always, no promises!
ISeeTWizard 29 Posted July 28, 2025 Posted July 28, 2025 13 minutes ago, yocker said: I's not so much if it's dynamic or not, they still use each their own detection as they have to know where to look. It has ofc. made it easier. I will look into it after i'm done with the icon overflow. As always, no promises! Thanks - As written I have no idea I was just asking me if the new system would it make easier Have fun with your icon overflow - It's like in the web development to get something to work in every browser lol And if you can do it great if not it's ok too - it would just make it easier for my kids to identify the movies 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now