Dark Theme Icons - a couple of hacks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello all,
I've implemented something similar to what @jeremy_tammik shows here: https://thebuildingcoder.typepad.com/blog/2023/01/dark-theme-possibility-looming.html
Hack 1:
I've long used .bmp files as my raw ribbon icon images.
I take those .bmp files and create .png files using a program called ImageMagick (https://imagemagick.org - I'm not affiliated).
Once installed you may use it in batch scripts etc:
https://imagemagick.org/script/command-line-processing.php
https://imagemagick.org/script/command-line-options.php
This what I used in Revit 2023:
rem For each .bmp file in this folder,
rem convert the white pixels to transparent,
rem and save the result to .png.
for %%f in (*.bmp) do ( convert -transparent white %%f %%~nf.png)
Then with Revit 2024, the Dark theme came along!
This is what I ended up with, in addition to the above:
rem For each .bmp file in this folder,
rem invert the grayscale pixels only (white->black, lightgray->darkgray, darkgray->lightgray, black->white etc etc)
rem convert the black pixels to transparent,
rem add 30 to each R,G,B value (necessary as our dark mode is not black - this is an arbitrary value to lighten the overall image),
rem and save the result to _dark.png.
for %%f in (*.bmp) do ( convert +negate -transparent black -colorize 30,30,30 %%f %%~nf_dark.png)
This system works well with grayscale icons, and icons that already used a similar colour scheme to native Revit.
I imagine it's possible to use the -scale switch to create 16x16 icons from 32x32 icons, but I've not tested that.
I imagine it's also possible to add badges (from the zip in Jeremy's post) to images using something like this: https://stackoverflow.com/questions/11095007/add-an-image-on-top-of-existing-one-with-imagemagick-co...
Hack 2:
Another issue I had was that I was using icons as embedded resources.
I couldn't work out how to get the name of the icon from the ribbon item Image or LargeImage property in order to get the dark or light equivalent. (I was changing the icons in the ThemeChanged event.)
I worked out I could embed the name within the BitMapSource when initially adding the image:
Private Shared Function GetEmbeddedImage(ByVal assembly As Assembly, ByVal imageFullName As String) As BitmapSource
If Not String.IsNullOrEmpty(imageFullName) Then
Dim s As IO.Stream = assembly.GetManifestResourceStream(imageFullName)
If s IsNot Nothing Then
Dim bitmap As BitmapSource = BitmapFrame.Create(s)
Dim metadata As BitmapMetadata = New BitmapMetadata("png")
metadata.SetQuery("/iTXt/Keyword", imageFullName.ToCharArray())
Dim bitmapWithMetadata As BitmapSource = BitmapFrame.Create(bitmap, Nothing, metadata, Nothing)
Return bitmapWithMetadata
End If
End If
Return Nothing
End Function
I could then retrieve that name:
Dim ribbonItem as RibbonItem...
Dim bitmapSource As BitmapSource = CType(ribbonItem.Image, BitmapSource)
Dim metadata As BitmapMetadata = CType(bitmapSource.Metadata, BitmapMetadata)
If metadata IsNot Nothing Then
Dim existingValue As Object = metadata.GetQuery("/iTXt/Keyword")
Dim imageName As String = TryCast(existingValue, String)
'Use image name to get an embedded resource and set it to the ribbon item image.
End If
I hope this saves some of you a bit of time and effort.
Cheers,
-Matt
_______________________________________________________________________________
Marking a post as a 'solution' helps the community. Giving a post 'Kudos' is as good as saying thanks. Why not do both?