SkBitmapScaler.h revision f3b1eb4ea262e48c93db8f0975e16341596cd8ec
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/* 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright 2013 Google Inc. 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * found in the LICENSE file. 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef SkBitmapScaler_DEFINED 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define SkBitmapScaler_DEFINED 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "SkBitmap.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "SkConvolver.h" 13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/** \class SkBitmapScaler 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Provides the interface for high quality image resampling. 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SK_API SkBitmapScaler { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public: 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) enum ResizeMethod { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Quality Methods 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Those enumeration values express a desired quality/speed tradeoff. 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // They are translated into an algorithm-specific method that depends 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // on the capabilities (CPU, GPU) of the underlying platform. 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // It is possible for all three methods to be mapped to the same 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // algorithm on a given platform. 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Good quality resizing. Fastest resizing with acceptable visual quality. 31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // This is typically intended for use during interactive layouts 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // where slower platforms may want to trade image quality for large 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // increase in resizing performance. 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For example the resizing implementation may devolve to linear 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // filtering if this enables GPU acceleration to be used. 37b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // 38b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Note that the underlying resizing method may be determined 39b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // on the fly based on the parameters for a given resize call. 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // For example an implementation using a GPU-based linear filter 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // in the common case may still use a higher-quality software-based 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // filter in cases where using the GPU would actually be slower - due 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // to too much latency - or impossible - due to image format or size 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // constraints. 45b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) RESIZE_GOOD, 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Medium quality resizing. Close to high quality resizing (better 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // than linear interpolation) with potentially some quality being 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // traded-off for additional speed compared to RESIZE_BEST. 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This is intended, for example, for generation of large thumbnails 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (hundreds of pixels in each dimension) from large sources, where 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a linear filter would produce too many artifacts but where 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a RESIZE_HIGH might be too costly time-wise. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_BETTER, 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // High quality resizing. The algorithm is picked to favor image quality. 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_BEST, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Algorithm-specific enumerations 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Box filter. This is a weighted average of all of the pixels touching 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the destination pixel. For enlargement, this is nearest neighbor. 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // You probably don't want this, it is here for testing since it is easy to 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // compute. Use RESIZE_LANCZOS3 instead. 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_BOX, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_TRIANGLE, 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_LANCZOS3, 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_HAMMING, 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_MITCHELL, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // enum aliases for first and last methods by algorithm or by quality. 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_FIRST_QUALITY_METHOD = RESIZE_GOOD, 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_LAST_QUALITY_METHOD = RESIZE_BEST, 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_FIRST_ALGORITHM_METHOD = RESIZE_BOX, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RESIZE_LAST_ALGORITHM_METHOD = RESIZE_MITCHELL, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Resizes the given source bitmap using the specified resize method, so that 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the entire image is (dest_size) big. The dest_subset is the rectangle in 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // this destination image that should actually be returned. 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The output image will be (dest_subset.width(), dest_subset.height()). This 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will save work if you do not need the entire bitmap. 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The destination subset must be smaller than the destination image. 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static bool Resize(SkBitmap* result, 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SkBitmap& source, 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ResizeMethod method, 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int dest_width, int dest_height, 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SkIRect& dest_subset, 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SkConvolutionProcs&, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkBitmap::Allocator* allocator = NULL); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Alternate version for resizing and returning the entire bitmap rather than 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // a subset. 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static bool Resize(SkBitmap* result, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const SkBitmap& source, 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResizeMethod method, 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int dest_width, int dest_height, 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const SkConvolutionProcs&, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SkBitmap::Allocator* allocator = NULL); 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)