乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      我的Qt作品(9)Qt使用Cairo繪圖引擎提升抗鋸齒效果【開源】

       漢無為 2023-03-14 發(fā)布于湖北

      之前寫了一篇文章《Qt使用GDI繪圖(僅Windows平臺)》

      Qt使用GDI繪圖(僅Windows平臺)_libaineu2004的博客-CSDN博客

      本篇重點(diǎn)介紹Cairo繪圖引擎,Qt自帶的QPainter的繪圖效率和抗鋸齒效果都沒有cairo的好。cairo 的目標(biāo)是以跨平臺的方式在打印機(jī)和屏幕上產(chǎn)生相同的輸出,它正在成為 Linux? 圖形領(lǐng)域的重要軟件。GNOME、GTK+、Pango 等許多軟件已經(jīng)使用了它提供的 2D 功能。另外,cairo 還支持生成 PostScript 或 PDF 輸出,從而產(chǎn)生高質(zhì)量的打印結(jié)果。在理想情況下,cairo 的用戶可以在打印機(jī)和屏幕上獲得非常接近的輸出效果。

      一、Cairo簡介

      Cairo:C編寫的開源繪圖引擎(基于LGPL協(xié)議),大名鼎鼎的FireFox就是用這個繪圖引擎的。Cairo是非常流行的開源2D圖形渲染引擎庫,它支持包括X-Windos,Win32,圖像,pdf在內(nèi)的各種輸出設(shè)備。目前,Cairo已被廣泛的使用在多個平臺上來渲染圖形界面,包括Firefox/Webkit-EFL/GTK+/Poppler/Qt等等。Qt的QPainter提供的抗鋸齒效果沒有cairo的好。cairo是用C編寫的,但是為大多數(shù)常用的語言提供了綁定。選用 C 語言有助于創(chuàng)建新的綁定,同時在進(jìn)行C語言調(diào)用時可以提供高性能。應(yīng)該特別注意Python綁定,它支持快速原型開發(fā),而且降低了學(xué)習(xí)cairo繪圖API的門檻。Cairo的繪圖效率是接近GDI/GDIPlus的。經(jīng)過優(yōu)化算法,可以做到完全忽略繪圖效率上的差別。此外,gtk不如qt流行,Qt支持cairo。

      cairo 是一個矢量繪圖(vector drawing)庫,因此繪圖需要對圖形進(jìn)行幾何描述,而不是描述位圖中填充的像素。在采用位圖繪圖(bitmap drawing)時,按照預(yù)先決定的布局用預(yù)先決定的顏色填充一系列像素,而且圖形的質(zhì)量與位圖的大小成正比。 在放大或修改位圖圖像時,位圖繪圖方法的效果就會變差。圖像常常會變得模糊,就像是近距離觀看背投電視或其他大屏幕電視時的效果。在某一距離上,圖像可能看起來很清楚,但是靠近之后就會看到許多離散的點(diǎn)。因?yàn)閿?shù)據(jù)無法定義預(yù)先定義的像素之間應(yīng)該是什么,所以放大時會很明顯地?fù)p失清晰度。計(jì)算機(jī)繪圖系統(tǒng)和體系結(jié)構(gòu)很早就出現(xiàn)了,cairo 的設(shè)計(jì)借鑒了 PostScript 和 PDF 模型的許多經(jīng)驗(yàn)。cairo 之所以借鑒 PostScript 和 Portable Document Format(PDF)方法是因?yàn)?,它們都使用?shù)學(xué)語句定義圖像。由于用幾何方法表示圖像,所以可以在任何時候在一定范圍內(nèi)計(jì)算幾何描述,從而重新創(chuàng)建整個圖像(或一部分圖像)。圖形的幾何性質(zhì)被表示為點(diǎn)、曲線和直線(這些元素構(gòu)成了矢量)。

      Cairo samples 官方樣例

      Examples 官方案例

      Download

      Index of /snapshots 搶鮮版源碼

      Index of /releases 穩(wěn)定版源碼,提供了C/C++,Python,R語言的支持。pixman是它的依賴庫。

      https://github.com/freedesktop/cairo C語言源碼

      https://github.com/pygobject/pycairo Python bindings for cairo

      cairo / cairo-demos · GitLab

      二、Cairo使用示例

      例1、和Qt結(jié)合的原理是:Cairo畫圖到QImage的緩存(image.bits),再用QPainter把QImae貼圖出來。

      1. void MainWindow::paintEvent(QPaintEvent *pEvent)
      2. {
      3. Q_UNUSED(pEvent);
      4. //原生的繪圖
      5. QPainter p(this);
      6. p.drawLine(QPoint(0, 0), QPoint(150, 220));
      7. //使用cairo繪圖引擎
      8. const char *pVersion = cairo_version_string();
      9. qDebug() << pVersion;
      10. //創(chuàng)建一張圖QImage
      11. int iW = this->width();
      12. int iH = this->height();
      13. QImage image(iW, iH, QImage::Format_ARGB32);
      14. unsigned char *pData = image.bits();
      15. int iLineStride = image.bytesPerLine();
      16. //將此圖轉(zhuǎn)換為cairo圖
      17. cairo_surface_t *pCairoSurface = cairo_image_surface_create_for_data(pData, CAIRO_FORMAT_ARGB32, iW, iH, iLineStride);
      18. cairo_surface_set_device_scale(pCairoSurface, 1, 1);
      19. cairo_t *pCairoContext = cairo_create(pCairoSurface);
      20. cairo_surface_destroy(pCairoSurface);
      21. if (pCairoContext)
      22. {
      23. double x = 100.6, y = 328.0;
      24. double x1 = 102.4 + 100, y1 = 130.4,
      25. x2 = 153.6 + 240, y2 = 405.6,
      26. x3 = 230.4 + 400, y3 = 200;
      27. cairo_move_to(pCairoContext, x, y);
      28. cairo_curve_to(pCairoContext, x1, y1, x2, y2, x3, y3);
      29. cairo_set_line_width(pCairoContext, 1.0); //設(shè)置線寬
      30. cairo_set_source_rgb(pCairoContext, 1.0, 0.0, 0.0); //設(shè)置線顏色
      31. cairo_stroke(pCairoContext);
      32. cairo_destroy(pCairoContext);
      33. }
      34. //貼圖
      35. p.drawImage(this->rect(), image);
      36. }

      例2、讀圖片文件,并顯示

      1. //define params
      2. int width, height, channels;
      3. //read image data from file using stb_image.h
      4. unsigned char* data = stbi_load(imagePath.c_str(), &width, &height, &channels, STBI_rgb_alpha);
      5. //create surface with image size and format is ARGB32
      6. this->imageSource = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
      7. //get pointer of cairo data
      8. unsigned char * surface_data = cairo_image_surface_get_data(this->imageSource);
      9. //copy current data to surface pointer
      10. memcpy(surface_data, data, width * height * 4 * sizeof(unsigned char));
      11. //mark as dirty to refresh surface
      12. cairo_surface_mark_dirty(this->imageSource);
      13. //free image data
      14. free(data);

      或者

      1. int w, h;
      2. cairo_surface_t *image;
      3. image = cairo_image_surface_create_from_png ('data/romedalen.png');
      4. w = cairo_image_surface_get_width (image);
      5. h = cairo_image_surface_get_height (image);
      6. cairo_translate (cr, 128.0, 128.0);
      7. cairo_rotate (cr, 45* M_PI/180);
      8. cairo_scale (cr, 256.0/w, 256.0/h);
      9. cairo_translate (cr, -0.5*w, -0.5*h);
      10. cairo_set_source_surface (cr, image, 0, 0);
      11. cairo_paint (cr);
      12. cairo_surface_destroy (image);

      三、完整的工程源碼及庫文件

      本人使用的編程環(huán)境是QtCreator + MSVC2019 32/64位

      https:///libaineu2004/cairo_demo

      四、cairo的開源應(yīng)用案例是scribus軟件

      scribus是開源項(xiàng)目,使用C++/Qt GUI

      源碼檢索關(guān)鍵詞【cairo_image_surface_create_for_data】 

       Cairo畫圖到QImage的緩存(image.bits),再用QPainter把QImae貼圖出來。

      1. canvas.cpp
      2. void Canvas::drawContents(QPainter *psx, int clipx, int clipy, int clipw, int cliph)
      3. {
      4. ScPainter *painter=nullptr;
      5. QImage img = QImage(clipw * devicePixelRatio(), cliph * devicePixelRatio(), QImage::Format_ARGB32_Premultiplied);
      6. img.setDevicePixelRatio(devicePixelRatio());
      7. painter = new ScPainter(&img, img.width(), img.height(), 1.0, 0);
      8. painter->clear(palette().color(QPalette::Window));
      9. painter->newPath();
      10. painter->moveTo(0, 0);
      11. painter->lineTo(clipw, 0);
      12. painter->lineTo(clipw, cliph);
      13. painter->lineTo(0, cliph);
      14. painter->closePath();
      15. painter->setClipPath();
      16. painter->translate(-clipx, -clipy);
      17. painter->setZoomFactor(m_viewMode.scale);
      18. painter->translate(-m_doc->minCanvasCoordinate.x(), -m_doc->minCanvasCoordinate.y());
      19. painter->setLineWidth(1);
      20. painter->setFillMode(ScPainter::Solid);
      21. painter->end();
      22. psx->drawImage(clipx, clipy, img);
      23. delete painter;
      24. painter=nullptr;
      25. }

      桌面排版軟件Scribus v1.5.5源碼編譯,使用VS2017+Qt5.12.7環(huán)境_libaineu2004的博客-CSDN博客

      x1.skia

      Skia是一個開源的二維圖形庫,提供各種常用的API,并可在多種軟硬件平臺上運(yùn)行。谷歌Chrome瀏覽器、Chrome OS、Fuchsia、安卓、Flutter、火狐瀏覽器、火狐操作系統(tǒng)以及其它許多產(chǎn)品都使用它作為圖形引擎。Skia由谷歌出資管理,任何人都可基于BSD免費(fèi)軟件許可證使用Skia。Skia開發(fā)團(tuán)隊(duì)致力于開發(fā)其核心部分, 并廣泛采納各方對于Skia的開源貢獻(xiàn)。
      Qt+Skia組合也是繪圖的好方案

      Windows環(huán)境VS2017編譯skia庫,親測成功,借助skui的方法_libaineu2004的博客-CSDN博客

      x2.geogebra

      GeoGebra是自由且跨平臺的動態(tài)數(shù)學(xué)軟件,提供各級教育使用,包含了幾何、代數(shù)、表格、圖形、統(tǒng)計(jì)和微積分,集中在一個容易使用的軟件。

      www./classic

      www./calculator

      GeoGebra Classic - GeoGebra

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多