棚画像を分割する方法について(Qiita説明用)
Qiitaでこれを全部説明したところでニーズもないので、掻い摘んでの説明になります!
1.本の文字部分をマウスで選択
2.Enterで本の画像を送信
-ここから非同期-
3.画像を分割
4.OCR処理
5.取得した文字を本検索
-ここまで非同期-
6.画面に結果表示
今回は、「5.取得した文字を本検索」です。
Google Books APIでの利用となります。
Google Books APIの参考サイト
最初のきっかけはこのサイト
書籍検索APIはGoogleBooksAPIsがオススメ【導入も楽ちんです】:
https://manablog.org/google-books-apis/
このサイトを見て導入を決め、もろもろ調べ、Google公式マニュアルを参考に実装しました。
送受信するデータについて
他のサイトで山ほど情報があるので、説明する必要がないのですが、一応。。。
URLにパラメータを追加するだけで検索が行える!が他サイトの説明が多数となっておりますが、
検索結果の表示画面で、ページング処理も行いたいので、他のパラメータも追加して検索を実施します。
そして、Jsonフォーマットで返却されますが、C#上でどのように処理をするのか。という点では、
ニーズがあるかも。
受信データ(JSON)のクラス化
さて、まずはクラスにしてしまいましょう。
これはご存知かと思いますが、JSONをC#の構造体クラスに変換してくれるサービスがあります。
各種API連携する場合には、必須のWebツールだと考えております。
json2csharp:
http://json2csharp.com/
ということで、まずはベースとなるJSONデータを検索します。
https://www.googleapis.com/books/v1/volumes?q=生命と環境の化学
このJSONを、json2csharpへコピペ!
↓ Generate ↓
↓ Copy ↓
新しいクラスを作成して、貼り付け!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace sample2_1.Models.GoogleBooks
{
public class GoogleBooks
{
public class IndustryIdentifier
{
public string type { get; set; }
public string identifier { get; set; }
}
public class ReadingModes
{
public bool text { get; set; }
public bool image { get; set; }
}
public class ImageLinks
{
public string smallThumbnail { get; set; }
public string thumbnail { get; set; }
}
public class PanelizationSummary
{
public bool containsEpubBubbles { get; set; }
public bool containsImageBubbles { get; set; }
}
public class VolumeInfo
{
public string title { get; set; }
public List<string> authors { get; set; }
public string publishedDate { get; set; }
public string description { get; set; }
public List<IndustryIdentifier> industryIdentifiers { get; set; }
public ReadingModes readingModes { get; set; }
public int pageCount { get; set; }
public string printType { get; set; }
public string maturityRating { get; set; }
public bool allowAnonLogging { get; set; }
public string contentVersion { get; set; }
public ImageLinks imageLinks { get; set; }
public string language { get; set; }
public string previewLink { get; set; }
public string infoLink { get; set; }
public string canonicalVolumeLink { get; set; }
public string subtitle { get; set; }
public string publisher { get; set; }
public List<string> categories { get; set; }
public PanelizationSummary panelizationSummary { get; set; }
}
public class ListPrice
{
public double amount { get; set; }
public string currencyCode { get; set; }
}
public class RetailPrice
{
public double amount { get; set; }
public string currencyCode { get; set; }
}
public class ListPrice2
{
public double amountInMicros { get; set; }
public string currencyCode { get; set; }
}
public class RetailPrice2
{
public double amountInMicros { get; set; }
public string currencyCode { get; set; }
}
public class Offer
{
public int finskyOfferType { get; set; }
public ListPrice2 listPrice { get; set; }
public RetailPrice2 retailPrice { get; set; }
}
public class SaleInfo
{
public string country { get; set; }
public string saleability { get; set; }
public bool isEbook { get; set; }
public ListPrice listPrice { get; set; }
public RetailPrice retailPrice { get; set; }
public string buyLink { get; set; }
public List<Offer> offers { get; set; }
}
public class Epub
{
public bool isAvailable { get; set; }
public string acsTokenLink { get; set; }
}
public class Pdf
{
public bool isAvailable { get; set; }
public string acsTokenLink { get; set; }
}
public class AccessInfo
{
public string country { get; set; }
public string viewability { get; set; }
public bool embeddable { get; set; }
public bool publicDomain { get; set; }
public string textToSpeechPermission { get; set; }
public Epub epub { get; set; }
public Pdf pdf { get; set; }
public string webReaderLink { get; set; }
public string accessViewStatus { get; set; }
public bool quoteSharingAllowed { get; set; }
}
public class SearchInfo
{
public string textSnippet { get; set; }
}
public class Item
{
public string kind { get; set; }
public string id { get; set; }
public string etag { get; set; }
public string selfLink { get; set; }
public VolumeInfo volumeInfo { get; set; }
public SaleInfo saleInfo { get; set; }
public AccessInfo accessInfo { get; set; }
public SearchInfo searchInfo { get; set; }
}
public class RootObject
{
public string kind { get; set; }
public int totalItems { get; set; }
public List<Item> items { get; set; }
}
}
}
これで、受信データ(JSON)を変換することで、オブジェクトとして扱うことが出来ます。
送信データ処理
こちらも、別クラスを作って処理を行います。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Threading.Tasks;
namespace sample2_1.Models.GoogleBooks
{
public class GoogleBooksApi
{
public static async Task<GoogleBooks.RootObject> GetGoogleBooks(string s_word)
{
// 返却用オブジェクト
GoogleBooks.RootObject rootObject = new GoogleBooks.RootObject();
using (HttpClient client = new HttpClient())
{
var parameters = new Dictionary<string, string>()
{
{ "q", s_word },
{ "Country", "JP" },
{ "maxResults", "30" }
};
// パラメータつけてGET
HttpResponseMessage response = await client.GetAsync($"https://www.googleapis.com/books/v1/volumes?{await new FormUrlEncodedContent(parameters).ReadAsStringAsync()}");
response.EnsureSuccessStatusCode();
// 返却値をJSONからクラスへ変換
var serializer = new DataContractJsonSerializer(typeof(GoogleBooks.RootObject));
rootObject = (GoogleBooks.RootObject)serializer.ReadObject(await response.Content.ReadAsStreamAsync());
}
// 出来たオブジェクトを変換
return rootObject;
}
}
}
Controllerへ実装
上記で作ったメソッドを呼び出すだけですね。
簡単簡単。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Drawing;
using Amazon;
using Amazon.S3;
using Amazon.S3.Transfer;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using sample2_1.Models;
using sample2_1.Models.Const;
using sample2_1.Models.Interface;
using sample2_1.Models.GoogleVision;
using sample2_1.Models.GoogleBooks;
namespace sample2_1.Controllers
{
public class WorkController : Controller
{
// AmazonS3 インターフェイス
private static IAmazonS3 client;
public IActionResult Index()
{
-略-
}
[HttpPost("UploadFiles")]
public async Task<IActionResult> FileUpload(List<IFormFile> files)
{
-略-
}
// S3 ストレージへアップロード!
static async Task WritingAnObjectAsync(string s_upd_file_nm)
{
-略-
}
//asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_6.分割画面→Canvasオブジェクト- 追加
public IActionResult Canvas()
{
-略-
}
[HttpPost]
//FormからJsonを受け取り、クラス変換してくれます。
public string Cut([FromBody]CutData cutData)
{
// 1.Imageへ画面に表示している画像ファイルを読み込み
System.Drawing.Image image = null;
try
{
image = System.Drawing.Image.FromFile(@"C:\work\work.jpg");
}
catch (Exception e)
{
throw e;
}
// 2.Bitmapに範囲指定したサイズを設定
Bitmap destbmp = new Bitmap((int)cutData.width, (int)cutData.height);
// 3.Graphicsに読み込ませるBitmapを設定
Graphics graphics = Graphics.FromImage(destbmp);
// 4.[1]でロードした画像を描画
graphics.DrawImage(image, (cutData.x * -1) , (cutData.y * -1), image.Size.Width, image.Size.Height);
// 5.保存先の指定
var stream = new FileStream(@"C:\work\cutter.jpg", FileMode.Create);
// 6.保存処理
destbmp.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
// 7.後処理
stream.Close();
// 8.Google Vision API 認証準備
GCPVisonAPI ocr = new GCPVisonAPI();
// 9.戻り値stringの変数作成、画像をByteArrayで開く
string getText = "";
byte[] imageArray = System.IO.File.ReadAllBytes(@"C:\work\cutter.jpg");
// 10.Google Vision APIの実行
ocr.getTextAndRoi(imageArray, ref getText);
// 11.Google Books APIのパラメータ作成
GoogleBooks.RootObject rootObject = GoogleBooksApi.GetGoogleBooks(getText).Result;
// 12.検索結果の書籍名+著者名を返却する
string s_res = "";
foreach (var item in rootObject.items)
{
// タイトルの取得
s_res = item.volumeInfo.title;
s_res += " / ";
// 作者名を取得
var cnt = 0;
foreach (string s_author in item.volumeInfo.authors)
{
if (cnt != 0)
{
s_res += ",";
}
s_res += s_author;
cnt++;
}
// 1件目で終了!
break;
}
// 検索結果の書籍名+著者名を返却する
return s_res;
// 受けとった文字列を返却
//return getText;
// 受け取ったheightプロパティを画面に返す。
//return @"正常にCut出来ました!";
}
}
}
デバッグ実行!
前回同様、「生命と環境の化学」を選択して、Enter!ターンッ!
↓ 結果 ↓
「基礎から学ぶ生命・環境の化学 / 三浦洋四郎,船越浩海,岡崎三代」
ん?合ってるの?
GoogleBooksで実際に見てみましょう。
一応合ってるっぽい!良かった!
最後に
これで、一通り実装は完了です。
簡単なアプリケーションなら作れそうな気がしませんか?
是非、色々遊んでみてください。
開発編は一旦ここまで。
ネタはあるのですが、ありきたりな話なので、また時間がある時に・・・。
ちなみにこんな感じを想定
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_9.分割処理 DB登録-
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_10.本一覧画面 DB検索-
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_11.本一覧画面 ページング-
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_12.本詳細画面-
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -2_13.本修正画面→Google Books API検索-
ページングはそこそこ苦労しました。
未だに0件対応ちゃんとやってないし。。。
これからTanaToruの改修をもろもろやりきったら、また更新します。
次の予定は、サーバデプロイ編。
乞うご期待。
【是非お試しください】※完全無料です
TanaToru -本棚管理サービス-
https://app.zero-one-system.co.jp/TanaToru/