def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) has_alpha = False soft_mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) # discard opaque pixels has_alpha = bool(vals) if has_alpha: # Blend image onto a white background as otherwise Qt will render # transparent pixels as black background = QImage(image.size(), QImage.Format_ARGB32_Premultiplied) background.fill(Qt.white) painter = QPainter(background) painter.drawImage(0, 0, image) painter.end() image = background ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = bytes(ba.data()) if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) return self.write_image(data, w, h, 32, dct=True, soft_mask=soft_mask, cache_key=cache_key)
class MainWindow(QWidget): def __init__(self): QMainWindow.__init__(self) self.resize(500, 300) self.mainLayout = QHBoxLayout() self.chooseLayout = QHBoxLayout() self.layout = QVBoxLayout() self.pixLayout = QHBoxLayout() self.thresholdLayout = QHBoxLayout() self.timeLayout = QHBoxLayout() self.contoursLayout = QHBoxLayout() self.setLayout(self.mainLayout) self.setWindowTitle( "Image To Gcode V1.0 ----- build By yizheneng [email protected]") self.imageLabel = QLabel("image") self.mainLayout.addWidget(self.imageLabel) self.mainLayout.addLayout(self.layout) self.mainLayout.setStretchFactor(self.layout, 1) self.mainLayout.setStretchFactor(self.imageLabel, 3) self.pixLengthLabel = QLabel(u"像素大小(mm):") self.pixDoubleSpinBox = QDoubleSpinBox() self.pixDoubleSpinBox.setValue(1) self.pixDoubleSpinBox.setDecimals(6) self.pixLayout.addWidget(self.pixLengthLabel) self.pixLayout.addWidget(self.pixDoubleSpinBox) self.thresholdLabel = QLabel(u"阈值:") self.thresholdSpinBox = QSpinBox() self.thresholdSpinBox.valueChanged.connect(self.ThresholdValChange) self.thresholdSpinBox.setMaximum(255) self.thresholdSpinBox.setValue(120) self.thresholdLayout.addWidget(self.thresholdLabel) self.thresholdLayout.addWidget(self.thresholdSpinBox) self.timeLabel = QLabel(u"灼烧时间:") self.timeDoubleSpinBox = QDoubleSpinBox() self.timeDoubleSpinBox.setValue(0.3) self.timeLayout.addWidget(self.timeLabel) self.timeLayout.addWidget(self.timeDoubleSpinBox) self.chooseLabel = QLabel(u"只雕刻轮廓:") self.chooseBox = QCheckBox() self.chooseLayout.addWidget(self.chooseLabel) self.chooseLayout.addWidget(self.chooseBox) self.chooseBox.stateChanged.connect(self.ChooseValChanged) self.contoursWidthLabel = QLabel(u"边框宽度") self.ContoursWidthSpinBox = QSpinBox() self.ContoursWidthSpinBox.setEnabled(False) self.ContoursWidthSpinBox.setValue(1) self.contoursLayout.addWidget(self.contoursWidthLabel) self.contoursLayout.addWidget(self.ContoursWidthSpinBox) self.loadImageButton = QPushButton(u"加载图片") self.loadImageButton.clicked.connect(self.LoadImageButtonClicked) self.previewButton = QPushButton(u"预览") self.previewButton.clicked.connect(self.ThresholdValChange) self.makeCodeButton = QPushButton(u"生成G代码") self.makeCodeButton.clicked.connect(self.MakeGcode) self.layout.addLayout(self.pixLayout) self.layout.addLayout(self.thresholdLayout) self.layout.addLayout(self.timeLayout) self.layout.addLayout(self.chooseLayout) self.layout.addLayout(self.contoursLayout) self.layout.addWidget(self.loadImageButton) self.layout.addWidget(self.previewButton) self.layout.addWidget(self.makeCodeButton) def LoadImageButtonClicked(self): self.filePath = QFileDialog.getOpenFileName(self, u"选择图片文件", "", "Images (*.bmp)") if self.filePath == "": QMessageBox.warning(self, u"发生错误", u"没有选择可以识别的文件!!") return self.srcImage = QImage(self.filePath) self.grayImage = QImage(self.srcImage.size(), QImage.Format_Indexed8) for i in range(256): self.grayImage.setColor(i, qRgb(i, i, i)) for i in range(self.srcImage.width()): for j in range(self.srcImage.height()): temp = qGray(self.srcImage.pixel(i, j)) self.grayImage.setPixel(i, j, temp) self.srcImage = QImage(self.grayImage) self.resultImage = QImage(self.grayImage) self.imageLabel.setPixmap(QPixmap(self.srcImage)) def ChooseValChanged(self): self.ContoursWidthSpinBox.setEnabled(self.chooseBox.isChecked()) def ThresholdValChange(self): for i in range(self.srcImage.width()): for j in range(self.srcImage.height()): temp = self.srcImage.pixelIndex(i, j) if (temp >= self.thresholdSpinBox.value()): self.grayImage.setPixel(i, j, 255) else: self.grayImage.setPixel(i, j, 0) self.resultImage = QImage(self.grayImage) #如果选中了只雕刻轮廓 if self.chooseBox.isChecked(): img = np.zeros( (self.grayImage.height(), self.grayImage.width(), 1), np.uint8) for i in range(self.grayImage.width()): for j in range(self.grayImage.height()): img[j, i] = self.grayImage.pixelIndex(i, j) #提取轮廓 contours = cv.findContours(img, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE) img = np.zeros( (self.grayImage.height(), self.grayImage.width(), 1), np.uint8) cv.drawContours(img, contours[1][:-1], -1, (255, 255, 255), self.ContoursWidthSpinBox.value()) #转换轮廓到显示界面 for i in range(self.resultImage.width()): for j in range(self.resultImage.height()): if img[j, i] == 0: self.resultImage.setPixel(i, j, 255) else: self.resultImage.setPixel(i, j, 0) self.imageLabel.setPixmap(QPixmap(self.resultImage)) def MakeGcode(self): path = QFileDialog.getSaveFileName(self, u"选择保存路径", "", " (*.nc)") if path == "": QMessageBox.warning(self, u"发生错误", u"路径错误!!") return f = open(path, 'w') f.write("M5\n") for i in range(self.resultImage.width()): flag = False #检测这一行是否有点 for j in range(self.resultImage.height()): if self.resultImage.pixelIndex(i, j) < 128: flag = True break #如果这一行都没有点则跳过这一行 if flag: f.write("G0 Y%f\n" % (i * self.pixDoubleSpinBox.value())) else: continue if (i % 2) > 0: for j in range(self.resultImage.height()): if self.resultImage.pixelIndex(i, j) < 128: f.write("G0 X%f\n" % (j * self.pixDoubleSpinBox.value())) f.write("M3\n") f.write("G4 P%f\n" % self.timeDoubleSpinBox.value()) f.write("M5\n") else: for j in range(self.resultImage.height())[::-1]: if self.resultImage.pixelIndex(i, j) < 128: f.write("G0 X%f\n" % (j * self.pixDoubleSpinBox.value())) f.write("M3\n") f.write("G4 P%f\n" % self.timeDoubleSpinBox.value()) f.write("M5\n") f.write("M5\n") f.write("G0 X0 Y0\n") f.close() QMessageBox.information(self, u"成功", u"生成G代码文件成功!!")