mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Implemented scaling images
This commit is contained in:
		| @@ -3750,3 +3750,6 @@ Timo Weing | ||||
|  | ||||
| Jose Angel <joseangelpp@gmail.com> | ||||
|  for reporting a bug in default values for DVB-T | ||||
|  | ||||
| Andreas Baierl <post@andreasbaierl.de> | ||||
|  for implementing scaling images | ||||
|   | ||||
							
								
								
									
										1
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -9871,3 +9871,4 @@ Video Disk Recorder Revision History | ||||
|   Ehrnsperger). | ||||
| - Using a dummy OSD if no OSD provider is available is not considered an error any | ||||
|   more (thanks to Markus Ehrnsperger). | ||||
| - Implemented scaling images (thanks to Andreas Baierl). | ||||
|   | ||||
							
								
								
									
										77
									
								
								osd.c
									
									
									
									
									
								
							
							
						
						
									
										77
									
								
								osd.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: osd.c 5.1 2024/01/18 11:06:45 kls Exp $ | ||||
|  * $Id: osd.c 5.2 2024/01/18 12:04:57 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "osd.h" | ||||
| @@ -1139,6 +1139,49 @@ void cImage::Fill(tColor Color) | ||||
|       data[i] = Color; | ||||
| } | ||||
|  | ||||
| cImage *cImage::Scaled(double FactorX, double FactorY, bool AntiAlias) const | ||||
| { | ||||
|   int w = max(1, int(round(Width() * FactorX))); | ||||
|   int h = max(1, int(round(Height() * FactorY))); | ||||
|   cImage *i = new cImage(cSize(w, h)); | ||||
|   int RatioX = (Width() << 16) / i->Width(); | ||||
|   int RatioY = (Height() << 16) / i->Height(); | ||||
|  | ||||
|   if (!AntiAlias || FactorX <= 1.0 && FactorY <= 1.0) { | ||||
|      // Downscaling - no anti-aliasing: | ||||
|      int SourceY = 0; | ||||
|      for (int y = 0; y < i->Height(); y++) { | ||||
|          int SourceX = 0; | ||||
|          for (int x = 0; x < i->Width(); x++) { | ||||
|              tColor c1 = GetPixel(cPoint(SourceX >> 16, SourceY >> 16)); | ||||
|              i->SetPixel(cPoint(x, y), c1); | ||||
|              SourceX += RatioX; | ||||
|              } | ||||
|          SourceY += RatioY; | ||||
|          } | ||||
|      } | ||||
|   else { | ||||
|      // Upscaling - anti-aliasing: | ||||
|      int SourceY = 0; | ||||
|      for (int y = 0; y < i->Height(); y++) { | ||||
|          int SourceX = 0; | ||||
|          int sy = min(SourceY >> 16, Height() - 2); | ||||
|          uint8_t BlendY = 0xFF - ((SourceY >> 8) & 0xFF); | ||||
|          for (int x = 0; x < i->Width(); x++) { | ||||
|              int sx = min(SourceX >> 16, Width() - 2); | ||||
|              uint8_t BlendX = 0xFF - ((SourceX >> 8) & 0xFF); | ||||
|              tColor c1 = AlphaBlend(GetPixel(cPoint(sx, sy)),     GetPixel(cPoint(sx + 1, sy)),     BlendX); | ||||
|              tColor c2 = AlphaBlend(GetPixel(cPoint(sx, sy + 1)), GetPixel(cPoint(sx + 1, sy + 1)), BlendX); | ||||
|              tColor c3 = AlphaBlend(c1, c2, BlendY); | ||||
|              i->SetPixel(cPoint(x, y), c3); | ||||
|              SourceX += RatioX; | ||||
|              } | ||||
|          SourceY += RatioY; | ||||
|          } | ||||
|      } | ||||
|   return i; | ||||
| } | ||||
|  | ||||
| // --- cPixmapMemory --------------------------------------------------------- | ||||
|  | ||||
| cPixmapMemory::cPixmapMemory(void) | ||||
| @@ -1259,6 +1302,26 @@ void cPixmapMemory::DrawImage(const cPoint &Point, int ImageHandle) | ||||
|   Unlock(); | ||||
| } | ||||
|  | ||||
| void cPixmapMemory::DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias) | ||||
| { | ||||
|   Lock(); | ||||
|   const cImage *i = &Image; | ||||
|   if (!DoubleEqual(FactorX, 1.0) || !DoubleEqual(FactorY, 1.0)) | ||||
|      i = i->Scaled(FactorX, FactorY, AntiAlias); | ||||
|   DrawImage(Point, *i); | ||||
|   if (i != &Image) | ||||
|      delete i; | ||||
|   Unlock(); | ||||
| } | ||||
|  | ||||
| void cPixmapMemory::DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias) | ||||
| { | ||||
|   Lock(); | ||||
|   if (const cImage *Image = cOsdProvider::GetImageData(ImageHandle)) | ||||
|      DrawScaledImage(Point, *Image, FactorX, FactorY, AntiAlias); | ||||
|   Unlock(); | ||||
| } | ||||
|  | ||||
| void cPixmapMemory::DrawPixel(const cPoint &Point, tColor Color) | ||||
| { | ||||
|   Lock(); | ||||
| @@ -2118,6 +2181,18 @@ void cOsd::DrawImage(const cPoint &Point, int ImageHandle) | ||||
|      pixmaps[0]->DrawImage(Point, ImageHandle); | ||||
| } | ||||
|  | ||||
| void cOsd::DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias) | ||||
| { | ||||
|   if (isTrueColor) | ||||
|      pixmaps[0]->DrawScaledImage(Point, Image, FactorX, FactorY, AntiAlias); | ||||
| } | ||||
|  | ||||
| void cOsd::DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias) | ||||
| { | ||||
|   if (isTrueColor) | ||||
|      pixmaps[0]->DrawScaledImage(Point, ImageHandle, FactorX, FactorY, AntiAlias); | ||||
| } | ||||
|  | ||||
| void cOsd::DrawPixel(int x, int y, tColor Color) | ||||
| { | ||||
|   if (isTrueColor) | ||||
|   | ||||
							
								
								
									
										39
									
								
								osd.h
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								osd.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: osd.h 5.1 2021/05/21 12:54:08 kls Exp $ | ||||
|  * $Id: osd.h 5.2 2024/01/18 12:04:57 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __OSD_H | ||||
| @@ -447,6 +447,11 @@ public: | ||||
|        ///< Clears the image data by setting all pixels to be fully transparent. | ||||
|   void Fill(tColor Color); | ||||
|        ///< Fills the image data with the given Color. | ||||
|   cImage *Scaled(double FactorX, double FactorY, bool AntiAlias = false) const; | ||||
|        ///< Creates a copy of this image, scaled by the given factors. | ||||
|        ///< If AntiAlias is true and either of the factors is greater than 1.0, | ||||
|        ///< anti-aliasing is applied. | ||||
|        ///< The caller must delete the returned image once it is no longer used. | ||||
|   }; | ||||
|  | ||||
| #define MAXPIXMAPLAYERS    8 | ||||
| @@ -602,6 +607,23 @@ public: | ||||
|        ///< the given Point. ImageHandle must be a value that has previously been | ||||
|        ///< returned by a call to cOsdProvider::StoreImage(). If ImageHandle | ||||
|        ///< has an invalid value, nothing happens. | ||||
|   virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias = false) {}; | ||||
|        ///< Draws the given Image into this pixmap at the given Point and scales it. | ||||
|        ///< If AntiAlias is true and either of the factors is greater than | ||||
|        ///< 1.0, anti-aliasing is applied. | ||||
|        ///< This function should be 'pure', just like all the others. However, since it was | ||||
|        ///< introduced when this class was already in widespread use, the default was made | ||||
|        ///< empty, so that existing code will still compile. | ||||
|   virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias = false) {}; | ||||
|        ///< Draws the image referenced by the given ImageHandle into this pixmap at | ||||
|        ///< the given Point and scales it. ImageHandle must be a value that has | ||||
|        ///< previously been returned by a call to cOsdProvider::StoreImage(). | ||||
|        ///< If ImageHandle has an invalid value, nothing happens. | ||||
|        ///< If AntiAlias is true and either of the factors is greater than | ||||
|        ///< 1.0, anti-aliasing is applied. | ||||
|        ///< This function should be 'pure', just like all the others. However, since it was | ||||
|        ///< introduced when this class was already in widespread use, the default was made | ||||
|        ///< empty, so that existing code will still compile. | ||||
|   virtual void DrawPixel(const cPoint &Point, tColor Color) = 0; | ||||
|        ///< Sets the pixel at the given Point to the given Color, which is | ||||
|        ///< a full 32 bit ARGB value. If the alpha value of Color is not 0xFF | ||||
| @@ -700,6 +722,8 @@ public: | ||||
|   virtual void Fill(tColor Color); | ||||
|   virtual void DrawImage(const cPoint &Point, const cImage &Image); | ||||
|   virtual void DrawImage(const cPoint &Point, int ImageHandle); | ||||
|   virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias = false); | ||||
|   virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias = false); | ||||
|   virtual void DrawPixel(const cPoint &Point, tColor Color); | ||||
|   virtual void DrawBlendedPixel(const cPoint &Point, tColor Color, uint8_t AlphaLayer = ALPHA_OPAQUE); | ||||
|   virtual void DrawBitmap(const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false); | ||||
| @@ -857,6 +881,19 @@ public: | ||||
|        ///< returned by a call to cOsdProvider::StoreImage(). If ImageHandle | ||||
|        ///< has an invalid value, nothing happens. | ||||
|        ///< If this is not a true color OSD, this function does nothing. | ||||
|   virtual void DrawScaledImage(const cPoint &Point, const cImage &Image, double FactorX, double FactorY, bool AntiAlias = false); | ||||
|        ///< Draws the given Image on this OSD at the given Point and scales it. | ||||
|        ///< If AntiAlias is true and either of the factors is greater than | ||||
|        ///< 1.0, anti-aliasing is applied. | ||||
|        ///< If this is not a true color OSD, this function does nothing. | ||||
|   virtual void DrawScaledImage(const cPoint &Point, int ImageHandle, double FactorX, double FactorY, bool AntiAlias = false); | ||||
|        ///< Draws the image referenced by the given ImageHandle on this OSD at | ||||
|        ///< the given Point and scales it. ImageHandle must be a value that has | ||||
|        ///< previously been returned by a call to cOsdProvider::StoreImage(). | ||||
|        ///< If ImageHandle has an invalid value, nothing happens. | ||||
|        ///< If AntiAlias is true and either of the factors is greater than | ||||
|        ///< 1.0, anti-aliasing is applied. | ||||
|        ///< If this is not a true color OSD, this function does nothing. | ||||
|   virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); | ||||
|        ///< Checks whether the OSD can display the given set of sub-areas. | ||||
|        ///< The return value indicates whether a call to SetAreas() with this | ||||
|   | ||||
		Reference in New Issue
	
	Block a user