private static Color getColor(BitmapPlus.BitmapPlus a_bmpPlus, int a_x, int a_y, int a_widthPerCell, int a_heightPerCell) { int totalA = 0; int totalR = 0; int totalG = 0; int totalB = 0; for (int x = a_x; x < a_x + a_widthPerCell; ++x) { for (int y = a_y; y < a_y + a_heightPerCell; ++y) { var c = a_bmpPlus.GetPixel(x, y); totalA += c.A; totalR += c.R; totalG += c.G; totalB += c.B; } } int size = a_widthPerCell * a_heightPerCell; return Color.FromArgb(totalA / size, totalR / size, totalG / size, totalB / size); }
private static Color getCompatibleColor(BitmapPlus.BitmapPlus a_bmpPlus, int a_x, int a_y, int a_widthPerCell, int a_heightPerCell) { var color = getColor(a_bmpPlus, a_x, a_y, a_widthPerCell, a_heightPerCell); return CompatibleColor.FindNearestCompatibleColor(color); }
private void c_executeBtn_Click(object sender, EventArgs e) { // ないと思うけどnullチェック if (m_bitmap == null) { return; } // 実行確認 if (MessageBox.Show("Updates the active sheet. Are you sure?", "Note", MessageBoxButtons.YesNo) != DialogResult.Yes) { return; } // 出力対象のアクティブなシートを取得 var ws = Globals.ThisAddIn.Application.ActiveSheet as Excel.Worksheet; if (ws == null) { MessageBox.Show("No sheet."); return; } // DPIの取得 double dpiX, dpiY; Graphics g = this.CreateGraphics(); try { dpiX = g.DpiX; dpiY = g.DpiY; } finally { g.Dispose(); } // 出力結果のサイズを取得+チェック int lastX = m_bitmap.Width / (int)c_numResoHori.Value; int lastY = m_bitmap.Height / (int)c_numResoVert.Value; if (lastX > ws.Columns.Count) { MessageBox.Show(string.Format("Result width is too large. (Max = {0}, Result = {1})", ws.Columns.Count, lastX)); return; } if (lastY > ws.Rows.Count) { MessageBox.Show(string.Format("Result height is too large. (Max = {0}, Result = {1})", ws.Rows.Count, lastY)); return; } // Color Modeに従い色取得関数をセット GetColorMethod getColorMethod; if (c_colorModeAll.Checked) { getColorMethod = getColor; } else { getColorMethod = getCompatibleColor; } // 進捗状況を表示したいので、ProgressBarDialogを生成しておく using (var progressBar = new ProgressBarDialog()) { progressBar.c_progressBar.Minimum = 0; progressBar.c_progressBar.Maximum = lastX; // セルの色設定は時間がかかるので別スレッドで実行(結局UIスレッドの気がする) Globals.ThisAddIn.Dispatcher.BeginInvoke((Action)(() => { // 更新を無効化 (確実に戻したいのでfinallyで戻す) Globals.ThisAddIn.Application.ScreenUpdating = false; try { // ExcelのCellのサイズを変更する ws.Cells[1, 1].Resize[lastY].EntireRow.RowHeight = (double)c_numCellHeight.Value * 72 / dpiY; ws.Cells[1, 1].Resize[ColumnSize: lastX].EntireColumn.ColumnWidth = setColWidth(ws, (double)c_numCellWidth.Value, dpiX, 1); // セルに色を設定 int progress = 0; using (var bmpPlus = new BitmapPlus.BitmapPlus(m_bitmap)) { int widthPerCell = (int)c_numResoHori.Value; int heightPerCell = (int)c_numResoVert.Value; int transparencyColor = c_pbxTransparency.BackColor.ToArgb(); for (int x = 1, imageX = 0; x <= lastX; ++x, imageX += widthPerCell) { for (int y = 1, imageY = 0; y <= lastY; ++y, imageY += heightPerCell) { var color = getColorMethod(bmpPlus, imageX, imageY, widthPerCell, heightPerCell); if (c_cbxUseTransparency.Checked && color.ToArgb() == transparencyColor) { ws.Cells[y, x].Clear(); } else { ws.Cells[y, x].Interior.Color = color; } } // 進捗状況を更新 ++progress; progressBar.c_progressBar.Value = progress; // 結局UIスレッドなのでInvokeしないで大丈夫 Application.DoEvents(); // キャンセルチェック if (progressBar.IsCancelled) { return; } } } } finally { // 更新を戻す Globals.ThisAddIn.Application.ScreenUpdating = true; // 進捗ダイアログを閉じる progressBar.Close(); } })); // 進捗状況ダイアログを表示 var result = progressBar.ShowDialog(); } }