スポンサーリンク

Skia(4)SkBitmapをwxWidgetsで表示

SkiaのSkBitmapをwxWidgetsのwxBitmapに変換して表示する。

wxWidgetsがRGBなのに対して、SkiaはRGBをサポートしていないので、32bit→24bitへの変換が必要になる。変換関数らしきものを見つけたがどうしてもうまく動かなかったので手動で変換している。

// https://docs.wxwidgets.org/3.0/overview_helloworld.html

// プリプロセッサに以下二つを追加
// __WXMSW__
// WXUSINGDLL

// サブシステムをWindowsに設定(WinMainで呼び出すので)
// Windows (/SUBSYSTEM:WINDOWS)

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include <wx/gdicmn.h> // wxPointに必要
#include <wx/frame.h>  // wxFrameに必要

#ifdef _DEBUG
#pragma comment(lib,"wxbase32ud.lib")
#pragma comment(lib,"wxbase32ud_net.lib")
#pragma comment(lib,"wxbase32ud_xml.lib")
#pragma comment(lib,"wxmsw32ud_adv.lib")
#pragma comment(lib,"wxmsw32ud_aui.lib")
#pragma comment(lib,"wxmsw32ud_core.lib")
#pragma comment(lib,"wxmsw32ud_gl.lib")
#pragma comment(lib,"wxmsw32ud_html.lib")
#pragma comment(lib,"wxmsw32ud_media.lib")
#pragma comment(lib,"wxmsw32ud_propgrid.lib")
#pragma comment(lib,"wxmsw32ud_qa.lib")
#pragma comment(lib,"wxmsw32ud_ribbon.lib")
#pragma comment(lib,"wxmsw32ud_richtext.lib")
#pragma comment(lib,"wxmsw32ud_stc.lib")
#pragma comment(lib,"wxmsw32ud_webview.lib")
#pragma comment(lib,"wxmsw32ud_xrc.lib")

#else

#pragma comment(lib,"wxbase32u.lib")
#pragma comment(lib,"wxbase32u_net.lib")
#pragma comment(lib,"wxbase32u_xml.lib")
#pragma comment(lib,"wxmsw32u_adv.lib")
#pragma comment(lib,"wxmsw32u_aui.lib")
#pragma comment(lib,"wxmsw32u_core.lib")
#pragma comment(lib,"wxmsw32u_gl.lib")
#pragma comment(lib,"wxmsw32u_html.lib")
#pragma comment(lib,"wxmsw32u_media.lib")
#pragma comment(lib,"wxmsw32u_propgrid.lib")
#pragma comment(lib,"wxmsw32u_qa.lib")
#pragma comment(lib,"wxmsw32u_ribbon.lib")
#pragma comment(lib,"wxmsw32u_richtext.lib")
#pragma comment(lib,"wxmsw32u_stc.lib")
#pragma comment(lib,"wxmsw32u_webview.lib")
#pragma comment(lib,"wxmsw32u_xrc.lib")

#endif

#pragma comment(lib,"skia.dll.lib")

/////////////////////////////////////

#include "skia/include/core/SkCanvas.h"
#include "skia/include/core/SkBitmap.h"


/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

#include <string>

// SkBitmapをRGBの配列に変換
void
PixelRGB(std::vector<std::uint8_t>& rgb,const SkBitmap& skbmp) { if (!skbmp.readyToDraw()) { return; } if (skbmp.colorType() != kRGBA_8888_SkColorType && skbmp.colorType() != kBGRA_8888_SkColorType) { return; } rgb.clear(); int Width = skbmp.width(); int Height = skbmp.height(); size_t rowBytes = skbmp.rowBytes(); const SkImageInfo& info = skbmp.info(); int channels = info.bytesPerPixel(); std::uint8_t* pixels = (std::uint8_t*)skbmp.getPixels(); rgb.resize(Width * Height * 3); for (int i = 0; i < Height; i++) { for (int j = 0; j < Width; j++) { size_t pos_ppm = (i * Width + j) * 3; size_t pos_sk = (i * rowBytes + j * channels); rgb[pos_ppm + 0] = pixels[pos_sk + 2]; rgb[pos_ppm + 1] = pixels[pos_sk + 1]; rgb[pos_ppm + 2] = pixels[pos_sk + 0]; } } }
// ウィンドウ作成
class MyFrame : public wxFrame
{
  SkBitmap my_bitmap;
public:

    void PostCreate() {

      // 画像の作成・描画
      my_bitmap.setInfo(SkImageInfo::Make(400, 400, kBGRA_8888_SkColorType, kPremul_SkAlphaType));
      my_bitmap.allocPixels();
      SkCanvas canvas(my_bitmap);
      // 背景を白にクリア
      canvas.clear(SK_ColorWHITE);
      // 図形の描画
      SkPaint paint;
      paint.setStyle(SkPaint::kStroke_Style);
      paint.setStrokeWidth(5);
      paint.setColor(SK_ColorRED);
      canvas.drawCircle(200, 200, 100, paint);
      // OnPaintイベントを設定
      Bind(wxEVT_PAINT, &MyFrame::OnPaint, this);

      this->Layout(); // レイアウトの更新
    }


    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : wxFrame(NULL, wxID_ANY, title, pos, size)
    
    {
      // CallAfter : 現在処理中のイベントが終わったらPostCreateを実行
      // コンストラクタはウィンドウ生成イベント扱い
      CallAfter(&MyFrame::PostCreate);
    }

    // OnPaintイベント
    void OnPaint(wxPaintEvent& event) {

      // SkBitmapをRGBへ変換
      int width = my_bitmap.width();
      int height = my_bitmap.height();
      std::vector<std::uint8_t> rgb;
      rgb.resize(width * height * 3);

      // 変換関数(自作)呼び出し
      PixelRGB(rgb, my_bitmap);

      // RGBをwxImageへ変換
      wxImage img(width,height, (unsigned char*)rgb.data(), true);
      wxBitmap wxbitmap(img);

      // wxWidgetsのウィンドウに表示
      wxPaintDC dc(this);
      dc.DrawBitmap(wxbitmap, 0, 0, true);
    }

};

/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

// wxWidgetsのアプリケーション作成
class MyApp : public wxApp {
public:

  virtual bool OnInit() {
    MyFrame* frame = new MyFrame("Hello World", wxPoint(50, 50), wxSize(550, 550));
    frame->Show(true);

    return true;
  }

};

/////////////////////////////////////
/////////////////////////////////////
/////////////////////////////////////

// WinMainをマクロで定義
wxIMPLEMENT_APP(MyApp);

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: