mirror of
https://github.com/greenshot/greenshot
synced 2025-08-21 05:53:27 -07:00
Modified the Quantizer to Xiaolin Wu's, updated the BitmapBuffer to support 8BPP but you still need to know what to call.... (needs some additional refactoring)
git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1712 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
parent
3250eee533
commit
b464480bf6
7 changed files with 101 additions and 726 deletions
|
@ -136,7 +136,7 @@ namespace GreenshotPlugin.Core {
|
|||
// Set "this" rect to location 0,0
|
||||
// as the Cloned Bitmap is only the part we want to work with
|
||||
this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
|
||||
} else if (!ImageHelper.SupportsPixelFormat(sourceBmp)) {
|
||||
} else if (!ImageHelper.SupportsPixelFormat(sourceBmp) && PixelFormat.Format8bppIndexed != sourceBmp.PixelFormat) {
|
||||
throw new ArgumentException("Unsupported pixel format: " + sourceBmp.PixelFormat + " set clone to true!");
|
||||
} else {
|
||||
this.bitmap = sourceBmp;
|
||||
|
@ -268,11 +268,36 @@ namespace GreenshotPlugin.Core {
|
|||
Lock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the color at location x,y
|
||||
* Before the first time this is called the Lock() should be called once!
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the color index, for 8BPP, at location x,y
|
||||
/// </summary>
|
||||
/// <param name="x">X coordinate</param>
|
||||
/// <param name="y">Y Coordinate</param>
|
||||
/// <returns>index</returns>
|
||||
public byte GetColorIndexAt(int x, int y) {
|
||||
int offset = x*bytesPerPixel+y*stride;
|
||||
return pointer[offset];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the color index, for 8BPP, at location x,y
|
||||
/// </summary>
|
||||
/// <param name="x">X coordinate</param>
|
||||
/// <param name="y">Y Coordinate</param>
|
||||
/// <param name="color">Color index to set</param>
|
||||
public void SetColorIndexAt(int x, int y, byte color) {
|
||||
int offset = x * bytesPerPixel + y * stride;
|
||||
pointer[offset] = color;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the color at location x,y
|
||||
/// Before the first time this is called the Lock() should be called once!
|
||||
/// </summary>
|
||||
/// <param name="x">X coordinate</param>
|
||||
/// <param name="y">Y Coordinate</param>
|
||||
/// <returns>Color</returns>
|
||||
public Color GetColorAt(int x, int y) {
|
||||
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
|
||||
int offset = x*bytesPerPixel+y*stride;
|
||||
|
@ -282,11 +307,14 @@ namespace GreenshotPlugin.Core {
|
|||
return Color.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the color at location x,y
|
||||
* Before the first time this is called the Lock() should be called once!
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the color, without alpha, at location x,y
|
||||
/// Before the first time this is called the Lock() should be called once!
|
||||
/// </summary>
|
||||
/// <param name="x">X coordinate</param>
|
||||
/// <param name="y">Y Coordinate</param>
|
||||
/// <returns>Color</returns>
|
||||
public Color GetColorAtWithoutAlpha(int x, int y) {
|
||||
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
|
||||
int offset = x*bytesPerPixel+y*stride;
|
||||
|
@ -393,6 +421,9 @@ namespace GreenshotPlugin.Core {
|
|||
rIndex = 2;
|
||||
bytesPerPixel = 3;
|
||||
break;
|
||||
case PixelFormat.Format8bppIndexed:
|
||||
bytesPerPixel = 1;
|
||||
break;
|
||||
default:
|
||||
throw new FormatException("Bitmap.Pixelformat."+bitmap.PixelFormat+" is currently not supported. Supported: Format32bpp(A)Rgb, Format24bppRgb");
|
||||
}
|
||||
|
|
|
@ -993,10 +993,61 @@ namespace GreenshotPlugin.Core {
|
|||
return newImage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rotate the bitmap
|
||||
/// </summary>
|
||||
/// <param name="sourceBitmap"></param>
|
||||
/// <param name="rotateFlipType"></param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap RotateFlip(Bitmap sourceBitmap, RotateFlipType rotateFlipType) {
|
||||
Bitmap returnBitmap = Clone(sourceBitmap);
|
||||
returnBitmap.RotateFlip(rotateFlipType);
|
||||
return returnBitmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a quantizer, so we can check if it pays off to quantize
|
||||
/// </summary>
|
||||
/// <param name="sourceBitmap"></param>
|
||||
/// <returns>IColorQuantizer</returns>
|
||||
public static IColorQuantizer PrepareQuantize(Bitmap sourceBitmap) {
|
||||
IColorQuantizer quantizer = new WuColorQuantizer();
|
||||
quantizer.Prepare(sourceBitmap);
|
||||
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
||||
bbbSrc.Lock();
|
||||
for (int y = 0; y < bbbSrc.Height; y++) {
|
||||
for (int x = 0; x < bbbSrc.Width; x++) {
|
||||
quantizer.AddColor(bbbSrc.GetColorAt(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
return quantizer;
|
||||
}
|
||||
|
||||
public static Bitmap Quantize(Bitmap sourceBitmap, IColorQuantizer quantizer) {
|
||||
Bitmap result = new Bitmap(sourceBitmap.Width, sourceBitmap.Height, PixelFormat.Format8bppIndexed);
|
||||
List<Color> palette = quantizer.GetPalette(255);
|
||||
ColorPalette imagePalette = result.Palette;
|
||||
// copies all color entries
|
||||
for (Int32 index = 0; index < palette.Count; index++) {
|
||||
imagePalette.Entries[index] = palette[index];
|
||||
}
|
||||
result.Palette = imagePalette;
|
||||
|
||||
using (BitmapBuffer bbbDest = new BitmapBuffer(result, false)) {
|
||||
bbbDest.Lock();
|
||||
using (BitmapBuffer bbbSrc = new BitmapBuffer(sourceBitmap, false)) {
|
||||
bbbSrc.Lock();
|
||||
for (int y = 0; y < bbbSrc.Height; y++) {
|
||||
for (int x = 0; x < bbbSrc.Width; x++) {
|
||||
Color originalColor = bbbSrc.GetColorAt(x, y);
|
||||
Int32 paletteIndex = quantizer.GetPaletteIndex(originalColor);
|
||||
bbbDest.SetColorIndexAt(x,y, (byte)paletteIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue