private void BackgroundWorker_SingleUse_SaturateBitmap(object sender, DoWorkEventArgs args) { BackgroundWorker thisWorker = sender as BackgroundWorker; Bitmap inputBitmap = (Bitmap)args.Argument; //Convert to 64bpp Bitmap. Bitmap inputBitmap64; BitmapToBitmap_64bppArgb(inputBitmap, out inputBitmap64); thisWorker.ReportProgress(16, "Finished converting to 64bpp."); //Get bytes. byte[] inputBitmapBytes = BitmapToByte_64bppArgb(inputBitmap64); thisWorker.ReportProgress(32, "Finished converting Bitmap to byte[]."); //Get normalized. double[] inputBitmapNormalized = ByteToNormalizedPixels_64bppArgb(inputBitmapBytes); thisWorker.ReportProgress(48, "Finished converting byte[] to normalized pixels."); //Saturate colors. ColorVector cv1 = new ColorVector(B1_tb, G1_tb, R1_tb, A1_tb, bias1_tb); ColorVector cv2 = new ColorVector(B2_tb, G2_tb, R2_tb, A2_tb, bias2_tb); double[] outputBitmapNormalized = SaturateNormalizedPixels( inputBitmapNormalized, cv1, cv2 ); thisWorker.ReportProgress(64, "Finished saturating colors."); //Back to byte[]. byte[] recoverOutputBitmapBytes = NormalizedPixelsToByte_64bppArgb(outputBitmapNormalized); thisWorker.ReportProgress(80, "Finished converting normalized pixels to byte[]."); //Back to Bitmap. Bitmap outputBitmap = ByteToBitmap_64bppArgb(recoverOutputBitmapBytes, inputBitmap64); args.Result = outputBitmap; }
public double Dot(ColorVector otherColorVector) { return(this.bias * otherColorVector.bias * (this.R * otherColorVector.R + this.G * otherColorVector.G + this.B * otherColorVector.B + this.A * otherColorVector.A)); }
public static ColorVector[] GenerateColorVectorArray(List <string> textFields) { //Find which one's the vector. int indexOfVector = -1; double[] paramSweeper = new double[3]; //L:H:N for (int n = 0; n < textFields.Count; n++) { if (textFields[n].Contains(',')) //That's the sweep. { //Note that location. indexOfVector = n; //Make an array out of it. string[] paramSplit = textFields[n].Split(','); for (int m = 0; m < paramSplit.Length; m++) { paramSweeper[m] = Convert.ToDouble(paramSplit[m]); } } } //paramSweeper holds L:H:N. That is, [L,H). //Convert this to sweepedParam, which actually represents this linear space. double L = paramSweeper[0]; double H = paramSweeper[1]; int N = (int)paramSweeper[2]; double[] sweepedParam = new double[N]; for (int n = 0; n < N; n++) { sweepedParam[n] = L + (double)n * (H - L) / (double)N; } //From sweepedParam, generate the List<double[]>, constructorArrays. List <double[]> constructorArrays = new List <double[]>(); for (int n = 0; n < N; n++) { //Make one constructor array. double[] currentConstructorArray = new double[5]; for (int m = 0; m < currentConstructorArray.Length; m++) //m ranges [0,4]. { if (m != indexOfVector) { currentConstructorArray[m] = Convert.ToDouble(textFields[m]); } else { currentConstructorArray[m] = sweepedParam[n]; } } constructorArrays.Add(currentConstructorArray); } //From List<> currentConstructorArrays, generate ColorVector[]. ColorVector[] cvArray = new ColorVector[N]; for (int n = 0; n < cvArray.Length; n++) { cvArray[n] = new ColorVector(constructorArrays[n]); } return(cvArray); }
public Bitmap SaturateBitmap(MemoryStream outputBitmapMemoryStream, Bitmap inputBitmap64, ColorVector cv1, ColorVector cv2) { inputBitmap64.Save(outputBitmapMemoryStream, ImageFormat.Bmp); //Initialize primitives. byte[] currentPixelBytes = new byte[8]; ColorVector cv = new ColorVector(); byte[] cvBytesToCopy = new byte[8]; //Starting at HeaderOffset in inputBitmapMemoryStream. outputBitmapMemoryStream.Position = BitmapHeaderLength; for (long n = outputBitmapMemoryStream.Position; n < outputBitmapMemoryStream.Length; n += 8) { //Grab 8 bytes. //Convert them to a ColorVector. outputBitmapMemoryStream.Read(currentPixelBytes, 0, currentPixelBytes.Length); cv = new ColorVector(currentPixelBytes); //Dot that ColorVector with cv1 and cv2. //For whichever of cv1 and cv2 that has the bigger dot product, //Turn that ColorVector into a byte[8]. cvBytesToCopy = (cv1.Dot(cv) > cv2.Dot(cv)) ? cv1.ToByteArray() : cv2.ToByteArray(); //Transplant that byte[8] where the original 8 bytes were. outputBitmapMemoryStream.Position -= 8; outputBitmapMemoryStream.Write(cvBytesToCopy, 0, cvBytesToCopy.Length); } return(new Bitmap(outputBitmapMemoryStream)); }
public double[] SaturateNormalizedPixels(double[] inputNormalizedPixels, ColorVector saturator1, ColorVector saturator2) { //For each slot in normalizedPixels (section off blocks of 4 at a time in this case). double[] outputNormalizedPixels = new double[inputNormalizedPixels.Length]; for (int n = 0; n < outputNormalizedPixels.Length; n += 4) { //Make a temporary ColorVector for that slot ([n, n + 3]) ColorVector inputCurrentPixel = new ColorVector( inputNormalizedPixels[n], inputNormalizedPixels[n + 1], inputNormalizedPixels[n + 2], inputNormalizedPixels[n + 3], 1 ); double dot1 = inputCurrentPixel.Dot(saturator1); //Dot that temporary ColorVector against saturator1. double dot2 = inputCurrentPixel.Dot(saturator2); //Dot that temporary ColorVector against saturator2. //Compare these two dot products. Array.Copy(dot1 > dot2 ? saturator1.ToArray() : saturator2.ToArray(), 0, outputNormalizedPixels, n, 4); } return(outputNormalizedPixels); }