Core.addWeighted
Core.vconcat
Core.hconcat
Imgproc.resize
Core.copyMakeBorder
Mat.submat
Mat.copyTo
Imgproc.cvtColor
Imgproc.threshold
Core.bitwise_and
Core.merge
工具类见 http://www.gaohaiyan.com/3229.html
本例完整代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JRadioButton; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.Rect; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; /** * 图片透明叠加、边框、拷贝叠加 */ public class Merge extends JFrame { private JLabel imageView; private boolean isConcat = false; private boolean isBorder = false; private double alpha = 0; private double beta = 0; private double gamma = 0; private int concat = 1; private int forwad = 0; private float border = 0; private Mat srcMat1; private Mat srcMat2; private Mat srcMat3; public Merge(String img1, String img2, String img3) { JLabel alphaLabel = new JLabel("alpha:" + alpha); alphaLabel.setBounds(15, 10, 120, 25); JSlider alphaBar = new JSlider(0, 20); alphaBar.setValue((int) alpha); alphaBar.setBounds(80, 10, 150, 25); alphaBar.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { alpha = alphaBar.getValue() * 1.0d; alphaLabel.setText("alpha:" + alpha); setPic(); } }); JLabel betaLabel = new JLabel("beta:" + beta); betaLabel.setBounds(15, 30, 120, 25); JSlider betaBar = new JSlider(0, 20); betaBar.setValue((int) beta); betaBar.setBounds(80, 30, 150, 25); betaBar.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { beta = betaBar.getValue() * 1.0d; betaLabel.setText("beta:" + beta); setPic(); } }); JLabel gammaLabel = new JLabel("gamma:" + gamma); gammaLabel.setBounds(15, 50, 120, 25); JSlider gammaBar = new JSlider(0, 100); gammaBar.setValue((int) gamma); gammaBar.setBounds(80, 50, 150, 25); gammaBar.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { gamma = gammaBar.getValue(); gammaLabel.setText("gamma:" + gamma); setPic(); } }); JCheckBox concatBtn = new JCheckBox("拼接"); concatBtn.setBounds(240, 10, 60, 25); concatBtn.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { isConcat = !isConcat; concatPic(); } }); JLabel concatLabel = new JLabel("数量:" + concat); concatLabel.setBounds(300, 10, 40, 25); JSlider concatBar = new JSlider(1, 5); concatBar.setValue(1); concatBar.setBounds(340, 10, 120, 25); concatBar.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { concat = concatBar.getValue(); concatLabel.setText("数量:" + concat); concatPic(); } }); JRadioButton hBtn = new JRadioButton("水平"); hBtn.setBounds(460, 10, 60, 25); hBtn.setSelected(true); hBtn.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { forwad = 0; } }); JRadioButton vBtn = new JRadioButton("垂直"); vBtn.setBounds(520, 10, 60, 25); vBtn.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { forwad = 1; } }); ButtonGroup group = new ButtonGroup(); group.add(hBtn); group.add(vBtn); JCheckBox borderBtn = new JCheckBox("边框"); borderBtn.setBounds(10, 80, 60, 25); borderBtn.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { isBorder = !isBorder; borderPic(); } }); JLabel borderLabel = new JLabel("宽度:" + 0); borderLabel.setBounds(80, 80, 60, 25); JSlider borderBar = new JSlider(0, 5); borderBar.setValue(0); borderBar.setBounds(140, 80, 120, 25); borderBar.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { border = borderBar.getValue() / 100f; borderLabel.setText("宽度:" + border); borderPic(); } }); JCheckBox compBtn = new JCheckBox("叠加"); compBtn.setBounds(10, 110, 60, 25); compBtn.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { compPic(compBtn.isSelected()); } }); JCheckBox irregularBtn = new JCheckBox("不规则叠加"); irregularBtn.setBounds(80, 110, 140, 25); irregularBtn.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { irregularPic(irregularBtn.isSelected()); } }); srcMat1 = Imgcodecs.imread(img1);//, Imgcodecs.CV_LOAD_IMAGE_COLOR); srcMat2 = Imgcodecs.imread(img2); srcMat3 = Imgcodecs.imread(img3);//, Imgcodecs.CV_LOAD_IMAGE_COLOR); int width = srcMat1.width(); int height = srcMat1.height(); imageView = new JLabel(""); imageView.setBounds(40, 120, width + 50, height + 50); this.setTitle("图片透明叠加、边框、拷贝叠加"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(width + 100, height + 250); this.getContentPane().setLayout(null); this.getContentPane().add(alphaLabel); this.getContentPane().add(alphaBar); this.getContentPane().add(betaLabel); this.getContentPane().add(betaBar); this.getContentPane().add(gammaLabel); this.getContentPane().add(gammaBar); this.getContentPane().add(concatBtn); this.getContentPane().add(concatLabel); this.getContentPane().add(concatBar); this.getContentPane().add(hBtn); this.getContentPane().add(vBtn); this.getContentPane().add(borderBtn); this.getContentPane().add(borderLabel); this.getContentPane().add(borderBar); this.getContentPane().add(compBtn); this.getContentPane().add(irregularBtn); this.getContentPane().add(imageView); setIcon(srcMat1); } private void setPic() { Mat mat = new Mat(srcMat1.rows(), srcMat1.cols(), srcMat1.type()); // Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst Core.addWeighted(srcMat1, alpha / 10, srcMat2, beta / 10, gamma, mat); // 图片叠加 src1*alpha+src2*beta+gamma setIcon(mat); } private void concatPic() { int rows = srcMat1.rows(); int cols = srcMat1.cols(); int ir = (int) (rows / concat); // 缩小 int ic = (int) (cols / concat); Mat concatMat = new Mat(ir, ic, srcMat1.type()); Imgproc.resize(srcMat1, concatMat, concatMat.size(), 1 / concat, 1 / concat, 0); // 先缩小,便有显示 List<Mat> matList = new ArrayList<>(); for (int i = 0; i < concat; i++) { matList.add(concatMat); } Mat mat = new Mat(); if (0 == forwad) { Core.hconcat(matList, mat); // 再拼接 } else { Core.vconcat(matList, mat); } setIcon(mat); } private void borderPic() { if (isBorder) { int rows = srcMat1.rows(); int cols = srcMat1.cols(); float top = border * rows; float bottom = border * rows; float left = border * cols; float right = border * cols; Mat dstMat = new Mat(rows, cols, srcMat1.type()); Core.copyMakeBorder(srcMat1, dstMat, (int) top, (int) bottom, (int) left, (int) right, 2); // 边框样式: //BORDER_CONSTANT = 0, 黑色 //BORDER_REPLICATE = 1, 边线拖放 //BORDER_REFLECT = 2, 从边线向外镜面反射 //BORDER_WRAP = 3, 上下左右互换 setIcon(dstMat); } else { setIcon(srcMat1); } } private void compPic(boolean comp) { if (comp) { Mat tmpMat = srcMat1.clone(); Rect roi = new Rect(150, 50, 90, 62); Mat dstMat = tmpMat.submat(roi); // submat方法按roi的区域从tmpMat拷贝了一块图片。这里用于放上新图片 Mat mask = srcMat3; // mask图片的纯黑部分会透明化处理。png格式优于jpg格式。 srcMat3.copyTo(dstMat, mask); // 将srcMat2放到dstMat上。遮罩使用srcMat2 setIcon(tmpMat); } else { setIcon(srcMat1); } } private void irregularPic(boolean irregular) { if (!irregular) { setIcon(srcMat1); return; } Mat maskMat = new Mat(); Imgproc.cvtColor(srcMat3, maskMat, Imgproc.COLOR_BGR2GRAY); // 将小图片转为灰阶图 Imgproc.threshold(maskMat, maskMat, 230, 255, Imgproc.THRESH_BINARY_INV); // 调整灰阶图,原始图纯白的变为纯黑的,其它像素转为纯白 List<Mat> planes = new ArrayList<Mat>(); Core.split(srcMat3, planes); // 拆分小图原始数据的BGR通道 Mat result1 = new Mat(); Mat result2 = new Mat(); Mat result3 = new Mat(); Core.bitwise_and(planes.get(0), maskMat, result1); // 和灰阶图进行逻辑与运算,使白色部分透明 Core.bitwise_and(planes.get(1), maskMat, result2); Core.bitwise_and(planes.get(2), maskMat, result3); List<Mat> result = new ArrayList<Mat>(); result.add(result1); result.add(result2); result.add(result3); Mat transparentMat = new Mat(); Core.merge(result, transparentMat); // 合并通道,得到白色變为透明的图片 Mat tmpMat = srcMat1.clone(); Rect roi = new Rect(50, 50, 90, 62); // 大图的一块区域 Mat destinationROI = tmpMat.submat(roi); // 大图上指定区域的子图 transparentMat.copyTo(destinationROI, transparentMat); // 再把小图copy到大图。指定了mask则进行透明处理。jpg和png效果相同 setIcon(tmpMat); } private void setIcon(Mat mat) { BufferedImage image = CVUtil.matToBufferedImage(mat); // CVUtil 见 http://www.gaohaiyan.com/3229.html imageView.setIcon(new ImageIcon(image)); } } |
- end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/3244.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设