@@ -58,6 +58,7 @@ public EffectType Type
5858 UpdateDirectionAttribute ( ) ;
5959 UpdateMovementRateAttribute ( ) ;
6060 UpdateCenterStopAttribute ( ) ;
61+ UpdateSizingAttribute ( ) ;
6162 OnPropertyChanged ( ) ;
6263 }
6364 }
@@ -150,6 +151,23 @@ public Curve YOffsetCurve
150151 }
151152 }
152153
154+ [ Value ]
155+ [ ProviderCategory ( @"Movement" , 1 ) ]
156+ [ ProviderDisplayName ( @"Sizing" ) ]
157+ [ ProviderDescription ( @"Sizing" ) ]
158+ [ PropertyOrder ( 7 ) ]
159+ public Curve SizingCurve
160+ {
161+ get { return _data . ScalingCurve ; }
162+ set
163+ {
164+ _data . ScalingCurve = value ;
165+ IsDirty = true ;
166+ UpdateSizingAttribute ( ) ;
167+ OnPropertyChanged ( ) ;
168+ }
169+ }
170+
153171 [ Value ]
154172 [ ProviderCategory ( @"Movement" , 1 ) ]
155173 [ ProviderDisplayName ( @"PictureCenterStop" ) ]
@@ -415,6 +433,7 @@ private void UpdateAttributes()
415433 UpdateStringOrientationAttributes ( ) ;
416434 UpdatePictureSourceAttribute ( false ) ;
417435 UpdateCenterStopAttribute ( false ) ;
436+ UpdateSizingAttribute ( false ) ;
418437 TypeDescriptor . Refresh ( this ) ;
419438 }
420439
@@ -470,6 +489,24 @@ private void UpdateCenterStopAttribute(bool refresh = true)
470489 }
471490 }
472491
492+ /// <summary>
493+ /// Determines when the 'Sizing' setting is applicable.
494+ /// </summary>
495+ private void UpdateSizingAttribute ( bool refresh = true )
496+ {
497+ // Sizing is only applicable for movement type of Resize
498+ bool resizeApplicable = Type == EffectType . RenderPictureResize ;
499+
500+ Dictionary < string , bool > propertyStates = new Dictionary < string , bool > ( 1 )
501+ {
502+ { nameof ( SizingCurve ) , resizeApplicable }
503+ } ;
504+ SetBrowsable ( propertyStates ) ;
505+ if ( refresh )
506+ {
507+ TypeDescriptor . Refresh ( this ) ;
508+ }
509+ }
473510
474511 private void UpdateMovementRateAttribute ( bool refresh = true )
475512 {
@@ -753,13 +790,28 @@ private void InitialRender(int frame, double intervalPosFactor)
753790
754791 if ( _pictures . Count > 0 )
755792 {
756- for ( int i = 0 ; i < _pictures . Count ; i ++ )
793+ if ( Type == EffectType . RenderPictureResize && _pictures . Count == 1 )
794+ {
795+ _fp = new FastPixel . FastPixel ( ScaleImage ( _pictures [ 0 ] . bitmap , CalculateSizing ( GetEffectTimeIntervalPosition ( frame ) * 100 ) ) ) ;
796+ }
797+
798+ else
757799 {
758- if ( frame >= _pictures [ i ] . frame )
800+ for ( int i = 0 ; i < _pictures . Count ; i ++ )
759801 {
760- _fp = new FastPixel . FastPixel ( _pictures [ i ] . bitmap ) ;
761- _pictures . RemoveAt ( i ) ;
762- break ;
802+ if ( frame >= _pictures [ i ] . frame )
803+ {
804+ if ( Type == EffectType . RenderPictureResize )
805+ {
806+ _fp = new FastPixel . FastPixel ( ScaleImage ( _pictures [ i ] . bitmap , CalculateSizing ( GetEffectTimeIntervalPosition ( frame ) * 100 ) ) ) ;
807+ }
808+ else
809+ {
810+ _fp = new FastPixel . FastPixel ( _pictures [ i ] . bitmap ) ;
811+ }
812+ _pictures . RemoveAt ( i ) ;
813+ break ;
814+ }
763815 }
764816 }
765817 }
@@ -971,6 +1023,15 @@ private void CalculatePixel(int x, int y, IPixelFrameBuffer frameBuffer, int fra
9711023 }
9721024 switch ( Type )
9731025 {
1026+ case EffectType . RenderPictureResize :
1027+ if ( TargetPositioning == TargetPositioningType . Locations )
1028+ {
1029+ locationY = _yoffset - y + _yOffsetAdj ;
1030+ locationX = x + _xoffset - _xOffsetAdj ;
1031+ break ;
1032+ }
1033+ frameBuffer . SetPixel ( xCoord - _xoffset + _xOffsetAdj , _yoffset - yCoord + _yOffsetAdj , fpColor ) ;
1034+ return ;
9741035 case EffectType . RenderPicturePeekaboo0 :
9751036 if ( TargetPositioning == TargetPositioningType . Locations )
9761037 {
@@ -1188,6 +1249,11 @@ private double CalculateIncreaseBrightness(double intervalPos)
11881249 return ScaleCurveToValue ( IncreaseBrightnessCurve . GetValue ( intervalPos ) , 100 , 10 ) ;
11891250 }
11901251
1252+ private double CalculateSizing ( double intervalPos )
1253+ {
1254+ return ScaleCurveToValue ( SizingCurve . GetValue ( intervalPos ) , 100 , 0 ) / 100 ;
1255+ }
1256+
11911257 private Color CustomColor ( int frame , double level , Color fpColor , double adjustedBrightness )
11921258 {
11931259 if ( ColorEffect == ColorEffect . CustomColor )
@@ -1248,6 +1314,10 @@ public static Bitmap ScaleImage(Image image, double scale)
12481314 var newWidth = ( int ) ( image . Width * ratio ) ;
12491315 var newHeight = ( int ) ( image . Height * ratio ) ;
12501316
1317+ // Make sure dimensions are at least 1 pixel
1318+ newWidth = Math . Max ( 1 , newWidth ) ;
1319+ newHeight = Math . Max ( 1 , newHeight ) ;
1320+
12511321 var newImage = new Bitmap ( newWidth , newHeight ) ;
12521322 using ( var g = Graphics . FromImage ( newImage ) )
12531323 {
0 commit comments