void Image::desaturate() { if (isARGB() || isRGB()) { const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); if (isARGB()) { for (int y = 0; y < destData.height; ++y) { uint8* p = destData.getLinePointer (y); for (int x = 0; x < destData.width; ++x) { ((PixelARGB*) p)->desaturate(); p += destData.pixelStride; } } } else { for (int y = 0; y < destData.height; ++y) { uint8* p = destData.getLinePointer (y); for (int x = 0; x < destData.width; ++x) { ((PixelRGB*) p)->desaturate(); p += destData.pixelStride; } } } } }
void Image::desaturate() { if (isARGB() || isRGB()) { const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); performPixelOp (destData, DesaturateOp()); } }
void Image::multiplyAlphaAt (const int x, const int y, const float multiplier) { if (isPositiveAndBelow (x, getWidth()) && isPositiveAndBelow (y, getHeight()) && hasAlphaChannel()) { const BitmapData destData (*this, x, y, 1, 1, BitmapData::readWrite); if (isARGB()) ((PixelARGB*) destData.data)->multiplyAlpha (multiplier); else *(destData.data) = (uint8) (*(destData.data) * multiplier); } }
void Image::createSolidAreaMask (RectangleList& result, const float alphaThreshold) const { if (hasAlphaChannel()) { const uint8 threshold = (uint8) jlimit (0, 255, roundToInt (alphaThreshold * 255.0f)); SparseSet<int> pixelsOnRow; const BitmapData srcData (*this, 0, 0, getWidth(), getHeight()); for (int y = 0; y < srcData.height; ++y) { pixelsOnRow.clear(); const uint8* lineData = srcData.getLinePointer (y); if (isARGB()) { for (int x = 0; x < srcData.width; ++x) { if (((const PixelARGB*) lineData)->getAlpha() >= threshold) pixelsOnRow.addRange (Range<int> (x, x + 1)); lineData += srcData.pixelStride; } } else { for (int x = 0; x < srcData.width; ++x) { if (*lineData >= threshold) pixelsOnRow.addRange (Range<int> (x, x + 1)); lineData += srcData.pixelStride; } } for (int i = 0; i < pixelsOnRow.getNumRanges(); ++i) { const Range<int> range (pixelsOnRow.getRange (i)); result.add (Rectangle<int> (range.getStart(), y, range.getLength(), 1)); } result.consolidate(); } } else { result.add (0, 0, getWidth(), getHeight()); } }
//============================================================================== void Image::clear (const Rectangle<int>& area, const Colour& colourToClearTo) { const Rectangle<int> clipped (area.getIntersection (getBounds())); if (! clipped.isEmpty()) { const PixelARGB col (colourToClearTo.getPixelARGB()); const BitmapData destData (*this, clipped.getX(), clipped.getY(), clipped.getWidth(), clipped.getHeight(), BitmapData::writeOnly); uint8* dest = destData.data; int dh = clipped.getHeight(); while (--dh >= 0) { uint8* line = dest; dest += destData.lineStride; if (isARGB()) { for (int x = clipped.getWidth(); --x >= 0;) { ((PixelARGB*) line)->set (col); line += destData.pixelStride; } } else if (isRGB()) { for (int x = clipped.getWidth(); --x >= 0;) { ((PixelRGB*) line)->set (col); line += destData.pixelStride; } } else { for (int x = clipped.getWidth(); --x >= 0;) { *line = col.getAlpha(); line += destData.pixelStride; } } } } }
void Image::multiplyAllAlphas (const float amountToMultiplyBy) { if (hasAlphaChannel()) { const BitmapData destData (*this, 0, 0, getWidth(), getHeight(), BitmapData::readWrite); if (isARGB()) { for (int y = 0; y < destData.height; ++y) { uint8* p = destData.getLinePointer (y); for (int x = 0; x < destData.width; ++x) { ((PixelARGB*) p)->multiplyAlpha (amountToMultiplyBy); p += destData.pixelStride; } } } else { for (int y = 0; y < destData.height; ++y) { uint8* p = destData.getLinePointer (y); for (int x = 0; x < destData.width; ++x) { *p = (uint8) (*p * amountToMultiplyBy); p += destData.pixelStride; } } } } else { jassertfalse; // can't do this without an alpha-channel! } }