Skip to content

update for Chrome Extension demo #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: feature/add-demo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ train_dataset/**
input/**
submission.txt
submit/**
download.sh

# model config
# configs/**
Expand Down
26 changes: 26 additions & 0 deletions demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# 부스트캠프 수식인식기 크롬익스텐션

## Getting Started
![image](demo.gif)
### Prerequisites
부스트캠프 수식인식기 모델이 있어야 합니다.
### Install

#### Server (server 폴더)
현재 서버코드는 모델관련된 코드가 적용되어 있지 않습니다. 이 부분은 대회에서 사용하셨던 inference코드를 수정하여서 적용해주세요
```
pip install -r requirements.txt
python main.py
```

기본적으로 `a ^ { 2 } + b ^ { 2 } = c ^ { 2 }` 가 반환되도록 설정되었습니다.

#### Chrome Extension (boost_susik 폴더)
1. 위에서 서버를 시작한 다음 그에 대응하는 URL을 `content.js` 상단에 변수로 넣어주세요!
```
const SERVERL_URL='http://<YOUR_SERVER_IP>:<YOUR_SERVER_PORT>/susik_recognize';
```
2. 크롬 주소창에 `chrome://extensions/` 다음 주소를 입력하고, `boost_susik`이라는 폴더를 `압축해제된 확장 프로그램을 로드합니다.` 버튼을 클릭하여 로드해주세요.



11 changes: 11 additions & 0 deletions demo/boost_susik/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
//스크린 캡쳐를 하는 코드
chrome.tabs.captureVisibleTab(null, {
format : "png",
quality : 100
}, function(data) {
sendResponse(data);
});
return true;
});

182 changes: 182 additions & 0 deletions demo/boost_susik/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
const SERVERL_URL='http://118.67.134.149:6012/susik_recognize';

fetch(chrome.runtime.getURL('/template.html')).then(r => r.text()).then(html => {
document.body.insertAdjacentHTML('beforeend', html);
});

let selectBoxX = -1
let selectBoxY = -1


document.body.addEventListener('click', e=>{
//하단에 박스 닫는 버튼 클릭시
if (e.target.id =='susik-close'){
let showBox = document.querySelector('#show-box');
let susikBox = document.querySelector('#susik-box');
let susikOutput = document.querySelector('#susik-output');
let susikImage = document.querySelector('#susik-image');
let susikLatex = document.querySelector('#susik-output-latex');

//관련된 UI들 초기화
showBox.style.display = 'none';
susikBox.style.width='0px';
susikBox.style.height='0px';
susikBox.style.top="-1px";
susikBox.style.left="-1px";
susikOutput.value = '';
susikImage.src = '';
susikLatex.src = '';
}
//fix 버튼 클릭시
if (e.target.id == 'fix-text'){
//latex image를 변경된 text에 맞추어 갱신
document.querySelector('#susik-output-latex').src = "http://latex.codecogs.com/gif.latex?" + document.querySelector('#susik-output').value
}
//copy 버튼 클릭시
if (e.target.id == 'copy-text'){
//text copy
copyText()
}
});


document.body.addEventListener('mousedown', e => {
var isActivated = document.querySelector('#susik-box').getAttribute("data-activate");
let susikBox = document.querySelector('#susik-box');
susikBox.style.display='block';

if(isActivated=="true"){
let x = e.clientX;
let y = e.clientY;
//Select Box의 시작점을 현재 마우스 클릭 지점으로 등록
selectBoxX = x;
selectBoxY = y;

//Susik Box이 위치와 사이즈를 현재 지점에서 초기화
susikBox.style.top = y+'px';
susikBox.style.left = x+'px';
susikBox.style.width='0px';
susikBox.style.height='0px';
}
});


//캡쳐가 준비된 상태에서 (마우스 클릭이 된 상태) 드래그시 박스 사이즈 업데이트
document.body.addEventListener('mousemove', e => {
try{
var susikBox = document.querySelector('#susik-box');
var isActivated = susikBox.getAttribute("data-activate");
}catch(e){
return;
}

//팝업에서 Start 버튼을 클릭하고, select 박스의 값이 초기값이 아닌 상태인 경우 시작
if(isActivated=="true" && (selectBoxX != -1 && selectBoxY != -1)){
let x = e.clientX;
let y = e.clientY;

//Select 박스(susik-box)의 가로 세로를 마우스 이동에 맞게 변경
width = x-selectBoxX;
height = y-selectBoxY;

susikBox.style.width = width+'px';
susikBox.style.height = height+'px';

}
});

// 마우스 드래그가 끝난 시점 (드랍)
document.body.addEventListener('mouseup', e => {
let susikBox = document.querySelector('#susik-box');
let isActivated = susikBox.getAttribute("data-activate");

//만약 팝업의 start 버튼을 클릭한 후의, 그냥 취소
if(isActivated=="false"){
return ;
}

// 다음 이벤트가 ??
susikBox.setAttribute("data-activate", "false");



let x = parseInt(selectBoxX);
let y = parseInt(selectBoxY);
let w = parseInt(susikBox.style.width);
let h = parseInt(susikBox.style.height);

//캡쳐 과정이 끝났으므로, susik-box 관련된 내용 초기화
selectBoxX = -1;
selectBoxY = -1;


susikBox.style.display='none';
susikBox.style.width='0px';
susikBox.style.height='0px';
susikBox.style.top="-1px";
susikBox.style.left="-1px";

//Overaly 화면 안보이게 초기화
document.querySelector('#overlay').style.display='none';
//마우스 Cursor도 원래 커서로 초기화
document.body.style.cursor = "default";


//200ms 정도의 시간차를 두고 서버로 현재 캡쳐된 이미지를 전송
//시간차를 안두면, 박스와 오버레이 화면이 같이 넘어갈 수 있음
setTimeout(function(){
chrome.runtime.sendMessage({text:"hello"}, function(response) {
var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
img.src=response;

function start(){
//화면 비율에 따라 원래 설정한 좌표 및 길이와 캡쳐본에서의 좌표와 길이가 다를 수가 있어서, 그에 대응하는 비율을 곱해줌
ratio = img.width/window.innerWidth;


var croppedURL=cropPlusExport(img,x*ratio,y*ratio,w*ratio,h*ratio);
var cropImg=new Image();
cropImg.src=croppedURL;
document.querySelector('#susik-image').src = croppedURL;
fetch(SERVERL_URL, {
method: 'POST',
body: JSON.stringify({"image":croppedURL}), // data can be `string` or {object}!
headers:{
'Content-Type': 'application/json'
}
}).then(res => res.json())
.then(response => {
document.querySelector('#susik-output').value = response['result'];
document.querySelector('#susik-output-latex').src = "http://latex.codecogs.com/gif.latex?" + response['result'];
});
}

});
},200);


});

//전체 스크린샷을 crop하는 함수
function cropPlusExport(img,cropX,cropY,cropWidth,cropHeight){


var canvas1=document.createElement('canvas');
var ctx1=canvas1.getContext('2d');
canvas1.width=cropWidth;
canvas1.height=cropHeight;

ctx1.drawImage(img,cropX,cropY,cropWidth,cropHeight,0,0,cropWidth,cropHeight);

return(canvas1.toDataURL());
}

//textbox의 내용을 copy하는 함수
function copyText() {
var obj = document.getElementById("susik-output");
obj.select(); //인풋 컨트롤의 내용 전체 선택
document.execCommand("copy"); //복사
obj.setSelectionRange(0, 0); //선택영역 초기화
}
Binary file added demo/boost_susik/images/boostsusik128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/boost_susik/images/boostsusik16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/boost_susik/images/boostsusik32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/boost_susik/images/boostsusik48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions demo/boost_susik/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "Boost Susik",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage", "activeTab", "scripting"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js"]
}
],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/boostsusik16.png",
"32": "/images/boostsusik32.png",
"48": "/images/boostsusik48.png",
"128": "/images/boostsusik128.png"
}
},
"icons": {
"16": "/images/boostsusik16.png",
"32": "/images/boostsusik32.png",
"48": "/images/boostsusik48.png",
"128": "/images/boostsusik128.png"
},
"web_accessible_resources": [
{
"resources": ["template.html"],
"matches": ["<all_urls>"]

}
]

}
9 changes: 9 additions & 0 deletions demo/boost_susik/popup.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<button id="select-susik" style="width:100px;height:50px;cursor:pointer;background-color: #209CEE; color:white;font-size:20px;">Start</button>
<script src="popup.js"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions demo/boost_susik/popup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Initialize button with user's preferred color
let selectSusik = document.getElementById("select-susik");



// When the button is clicked, inject setPageBackgroundColor into current page
selectSusik.addEventListener("click", async () => {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
window.close();
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: setSusikBox,
});
});


function setSusikBox() {
document.body.style.cursor = "cell";
document.querySelector('#susik-box').style.backgroundColor = 'none';
document.querySelector('#susik-box').setAttribute("data-activate", "true");
document.querySelector('#overlay').style.display = 'block';
document.querySelector('#show-box').style.display = 'block';

}
58 changes: 58 additions & 0 deletions demo/boost_susik/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<div id="overlay" style="top:0;left:0;background-color:rgba(0, 0, 0, 0.5); display:none; position:fixed;width: 100%;height: 100%; z-index: 2147483646;">
<div id="susik-box" data-activate = "false" style="border:3px dashed red; position:absolute; width: 0px; height:0px; z-index: 2147483647;display:none; ">
</div>
</div>
<div id="show-box" style="display:none; border-top:5px solid #eee; position:fixed; bottom:0px;z-index: 2147483647; width:100%; height:250px; background-color:white; padding-bottom: 15px;">
<span id="susik-close" style="position: absolute;
right: 5px;
font-size: 15px;
width: 20px;
height: 20px;
display: inline-block;
border-radius: 50%;
border: 1px solid black;
text-align: center;
background-color: black;
color: white;
top: -16px;
cursor: pointer;">X</span>
<div style="display: flex;justify-content: space-evenly; padding:5px; text-align:center;">
<table border="1" style="font-size:20px; width:700px;height:120px;">
<tr>
<td style="width:120px">
<p>captured<br>image</p>
</td>
<td>
<img style="max-height:100px;" id="susik-image" src="">
</td>
</tr>
</table>
<table border="1" style="font-size:20px; width:700px;height:120px;">
<tr>
<td style="width:120px">
<p>expected<br>latex</p>
</td>
<td>
<img style="height:80%;" id="susik-output-latex" src="">
</td>
</tr>
</table>
</div>
<div style="display: flex;justify-content: space-evenly; padding:5px;">
<table>
<tr>
<td rowspan="2" style="width:1510px;height:120px;">
<textarea id="susik-output" style="font-size:30px; width:99%;height:99%;"></textarea>
</td>
<td align="center">
<button id="fix-text" style="width:100%">fix</button>
</td>
</tr>
<tr>
<td>
<button id="copy-text">copy</button>
</td>
</tr>
</table>
</div>
</div>
Binary file added demo/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading