It is currently October 9th, 2024, 6:55 pm

Working with Bitmap

Our most popular Tips and Tricks from the Rainmeter Team and others
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Working with Bitmap

Post by jsmorley »

Bitmap meter

One of the meters that is not used as often in Rainmeter is the Bitmap meter. This is primarily due to the fact that the options can be a little hard to grasp at first, and that there is a fair amount of "outside" work that needs to be done in some kind of image editing tool.

However, if you take a little time to understand how it works, and are willing to use some creativity with PhotoShop or Gimp or Paint.NET or other image editor of choice, some very nice results can be had with this meter.

The Bitmap meter is an image-based meter that uses images laid out to create a bitmap. This is not the .bmp image format used in Windows, but a way in Rainmeter of talking about an image in any of the supported formats (.png, .jpg, .bmp, .tif) that can be divided into frames, based on the percentage value of a measure.

This is similar to how images are created for the Button meter, where the single image consists of equally sized frames, laid out either horizontally or vertically.

The meter then uses the percentage value of a measure in the MeasureName option, to divide the image into the separate frames for display. All you have to do is tell the meter what the MeasureName is, and how many logical frames there are in the image with the BitmapFrames option. The meter will take it from there.

It might help first thing, to show an example of a bitmap image. We will use this image again later in one of our examples.
Numbers.png
This is simply a .png image with the 10 numbers from 0 to 9, laid out horizontally and equally spaced. The image is 640 pixels wide, with each of the numbers taking up 64 pixels of width.

With this image, if we set a Bitmap meter with BitmapFrames=10, it will use the percentage measure value with that number of frames to determine which part of the image, which "frame", to display. This will become clearer as we look at our examples.

Some examples

First, here is a .rmskin with all three examples we will be discussing:
MeterBitmap_1.0.rmskin
Simpy install this .rmskin, and in Manage you can load the skin that you want to play with.

BitmapValue

Our first example uses the percentage value of a measure and displays the frame from the bitmap image that corresponds. This is the most basic and perhaps the most common use for a Bitmap meter.
BiitmapValue.jpg

Code: Select all

[Rainmeter]
Update=1000

[MeasureDayofYear]
Measure=Time
Format=%#j
MinValue=1
MaxValue=366

[MeterBitmapValue]
Meter=Bitmap
MeasureName=MeasureDayofYear
BitmapImage=#@#Images\Quarters.png
BitmapFrames=4

[MeterDayOfYear]
Meter=String
MeasureName=MeasureDayofYear
X=50
Y=4R
FontSize=12
FontColor=241,199,108,255
SolidColor=47,47,47,255
Padding=2,2,2,2
StringAlign=Center
AntiAlias=1
Text=Day: %1
What this is doing is getting the day of the year using a Time measure. This will be a value from 1 to 365. We set MinValue to 1 and MaxValue to 366 to allow the meter to see the measure as a percentual value.

Then we have our bitmap image, in this case laid out with four "frames":
Quarters.png
The meter will take the percentage that the measure value is at, divide the image into four BitmapFrames "frames", and display the portion of the image that corresponds to the percentage range. So in this case, the first quarter of the year is from day 1 to day 92 (1/4 of 365) and day 68 falls in that first 1/4 of the range. That "frame" of the image is displayed.

BitmapAnim

Another use of the Bitmap meter is to display an animation. For this use, you simply create a bitmap image with as many "frames" as you want in your animation, and loop through them one at a time.
BitmapAnim.gif

Code: Select all

[Rainmeter]
Update=45

[MeasureAnimLoop]
Measure=Calc
Formula=(MeasureAnimLoop + 1) % 37
MinValue=0
MaxValue=38

[MeterAnim]
Meter=Bitmap
MeasureName=MeasureAnimLoop
BitmapImage=#@#Images\XAnim.png
BitmapFrames=37
In this case we use a bitmap image like this. Click to see it a bit larger:
XAnim.png
Our counter Calc measure simply counts from 0 to 37, the same number we have in BitFrames=37, and displays that "frame" on each update. We are controlling the speed of the animation with the Update=45 option in the [Rainmeter] section of the skin.

BitmapDigits

The last example we will show uses a very powerful additional feature of the Bitmap meter. This allows us to use the meter to display a measure value's number as images, one for each "digit" of the value.

First, let's look at our result, code and the bitmap image we use. Then we will explain a bit how it works.
BitmapDigit.jpg

Code: Select all

[Rainmeter]
Update=1000

[MeasureCPU]
Measure=CPU

[MeterCellBack1]
Meter=Image
ImageName=#@#Images\CellBack.png
X=0
Y=0

[MeterCellBack2]
Meter=Image
ImageName=#@#Images\CellBack.png
X=3R
Y=0r

[MeterCellBack3]
Meter=Image
ImageName=#@#Images\CellBack.png
X=3R
Y=0r

[MeterCPU]
Meter=Bitmap
MeasureName=MeasureCPU
X=8
Y=8
BitmapImage=#@#Images\Numbers.png
BitmapFrames=10
BitmapExtend=1
BitmapDigits=3
BitmapSeparation=12

[MeterCellFore1]
Meter=Image
ImageName=#@#Images\CellFore.png
X=0
Y=0

[MeterCellFore2]
Meter=Image
ImageName=#@#Images\CellFore.png
X=3R
Y=0r

[MeterCellFore3]
Meter=Image
ImageName=#@#Images\CellFore.png
X=3R
Y=0r
Numbers.png
In addition, we are using two regular images as a part of our design. A background and foreground image:
CellBack.png
CellFore.png
First off, the meter is being driven by a simple CPU measure, which will return a percentage value from 0 to 100.

Next we have our bitmap image. If we think back to how the Bitmap meter worked for us in the BitValue example, We had a "frame" for each of the percentage value ranges that the measure returns. We certainly don't want to have to create a gigantic image that has all the possible numbers between 000 and 100, that would be a massive undertaking and make for a very large image file.

Let's see how we solve this...

Three additional options

BitmapDigits
With this option, you tell the meter how many digits the value can consist of. Since we are measuring a percentage between 0 and 100, the number of digits we want to display is 3. BitmapDigits=3

BitmapExtend
If set to 1, this will tell the meter to "extend" the display, to show BitmapDigits frames, with each corresponding to the "digit" of the measure value. So if the measure value is 25 as in our example, the meter will extend to display the frames for "0", "2" and "5".

BitmapSeparation
This is used to help with positioning the frames when BitmapExtend=1. You can use a negative or positive number to move the position of the frames relative to each other to the left or right (or up and down if the bitmap image is laid out vertically) until you get the look you want.

Take a close look at the code for this example above, hopefully it will become clear when you play around with it a bit.

Hope this helps with understanding the Bitmap meter. It can be used to create some very creative and active skins.
You do not have the required permissions to view the files attached to this post.
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with Bitmap

Post by jsmorley »

Nice for a digital clock of course..

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

[MeasureHours]
Measure=Time
Format=%I

[MeasureMinutes]
Measure=Time
Format=%M

[MeasureSeconds]
Measure=Time
Format=%S

[MeterBack]
Meter=Image
W=268
H=70
SolidColor=0,0,0,1

[MeterHours]
Meter=Bitmap
MeasureName=MeasureHours
BitmapImage=#CURRENTPATH#flip_clock.png
BitmapFrames=10
BitmapExtend=1
BitmapDigits=2
BitmapSeparation=0

[MeterMinutes]
Meter=Bitmap
MeasureName=MeasureMinutes
X=90
BitmapImage=#CURRENTPATH#flip_clock.png
BitmapFrames=10
BitmapExtend=1
BitmapDigits=2
BitmapSeparation=0

[MeterSeconds]
Meter=Bitmap
MeasureName=MeasureSeconds
X=180
BitmapImage=#CURRENTPATH#flip_clock.png
BitmapFrames=10
BitmapExtend=1
BitmapDigits=2
BitmapSeparation=0
flip_clock.png
2014-03-14_104937.jpg
You do not have the required permissions to view the files attached to this post.
xames3
Posts: 10
Joined: April 29th, 2018, 9:10 am

Re: Working with Bitmap

Post by xames3 »

@jsmorley is there any way of playing and png frame animation strip smoothly; Update = 10 and just once?
Like I'm building a skin which should run a png animation strip at the startup and then it should stop looping. The Update is set as 10 for the entire skin. I tried using UpdateDivider = -1 in the measures and meters, it didn't work for me.
Could you please help on this?

I've added the code as well
[Rainmeter]
Update = 10

[Metadata]
Name = Background Grid
Author = XAMES3
Information = This file displays a Background Grid which animates overtime. | Last Updated: Apr 27, 2018
Version = 1.0.0 - Created Date: Apr 27, 2018
License = Creative Commons Attribution-Non-Commercial-Share Alike 3.0

[Includes]
@Include = #@#\Configurations\Variables.inc

[MeasureAnimation]
Measure=Calc
Formula=(MeasureAnimation + 1) % 135
MinValue=0
MaxValue=136

[MeterAnimation]
Meter = Bitmap
MeasureName = MeasureAnimation
BitmapImage = #@#\Backgrounds\Static_Grid.png
BitmapFrames = 135
BitmapExtend = 1
UpdateDivider = -1
User avatar
fonpaolo
Moderator
Posts: 1387
Joined: April 11th, 2013, 8:08 pm
Location: Italy

Re: Working with Bitmap

Post by fonpaolo »

I think the best solution is to use ActionTimer.
High update rates are no longer needed.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5539
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Working with Bitmap

Post by eclectic-tech »

Another option would be to use a LOOP MEASURE; the advantage is the simplicity of the code and the ability to control the loop action. This will count from 1 to 135 and stop. The measure value will be 135, so the bitmap will remain visible. If you do not want the bitmap to remain showing, you can add an IfCondition to hide it when the loop value reaches 135.

Code: Select all

[MeasureAnimation]
Measure=Loop
StartValue=1
EndValue=135
Increment=1
LoopCount=1
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with Bitmap

Post by jsmorley »

I do think I would tend to lean toward using ActionTimer though. That way you can set the skin Update to 1000, and just have an OnRefreshAction that fires the ActionTimer measure. That measure will simply update [MeasureAnimation], update [MeterAnimation] and !Redraw. Do that 135 times, with a many or few milliseconds of "delay" between each that you want.

The advantage to this is that the overall skin doesn't have to be set to Update=16, which even on a simple skin is going to be doing a lot of work that won't be needed once the animation if finished. Just the redraws of the skin alone will be a bit expensive at that rate.
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with Bitmap

Post by jsmorley »

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
OnRefreshAction=[!CommandMeasure MeasureAction "Execute 1"]

[MeasureCount]
Measure=Calc
Formula=(MeasureCount %135) + 1
UpdateDivider=-1
Paused=1

[MeasureAction]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Start | Wait 1 | Repeat CountUp,16,135 | Wait 1 | Stop
Start=[!UnpauseMeasure MeasureCount]
CountUp=[!UpdateMeasure MeasureCount][!UpdateMeter MeterCount][!Redraw]
Stop=[!PauseMeasure MeasureCount]

[MeterCount]
Meter=String
MeasureName=MeasureCount
FontSize=15
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
This could certainly be done with a Loop measure rather than a Calc measure, using exactly the same approach. The difference is that it is easier to get a Loop measure to start with "1" rather than "0", if that is what you want.

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
OnRefreshAction=[!CommandMeasure MeasureAction "Execute 1"]

[MeasureCount]
Measure=Loop
StartValue=1
EndValue=135
UpdateDivider=-1
Paused=1

[MeasureAction]
Measure=Plugin
Plugin=ActionTimer
ActionList1=Start | Wait 10 | Repeat CountUp,16,135 | Wait 10 | Stop
Start=[!UnpauseMeasure MeasureCount]
CountUp=[!UpdateMeasure MeasureCount][!UpdateMeter MeterCount][!Redraw]
Stop=[!PauseMeasure MeasureCount]

[MeterCount]
Meter=String
MeasureName=MeasureCount
FontSize=15
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Working with Bitmap

Post by jsmorley »

xames3,

Attach or post a link to the bitmap image file you are using, and explain what effect you are going for, and I'm sure we can get you started.
xames3
Posts: 10
Joined: April 29th, 2018, 9:10 am

Re: Working with Bitmap

Post by xames3 »

Guys thanks for your help it is working though but the animation doesn't stops on last frame. I want the animation to run once every refresh/loading and the last frame should stay in place.
Also can some please explain the executions of the above code? That would be helpful for me to learn and understand future codes even better.
Thanks in advance!

@lsmorley saw your reply...
The bitmap png I'm using is what I've made in AfterEffects/Gamemaker and in Photoshop. Just like a sprite. (its very light and transparent)
The size of each frame is 1920*1080. Attached is for your reference.
I want the animation/last frame to stay after its done loading. Also is there any other way so that I can add other animation sprite on top of this with some delay?
What I really am for is first this static grid.png should start loading and while its loading other xyz.png animation sprite should load on top of it but with some delay. Is it achievable?
You do not have the required permissions to view the files attached to this post.
User avatar
fonpaolo
Moderator
Posts: 1387
Joined: April 11th, 2013, 8:08 pm
Location: Italy

Re: Working with Bitmap

Post by fonpaolo »

xames3 wrote:...
The size of each frame is 1920*1080. Attached is for your reference.
...
:17what