반응형

예전 포스트에서 포토샵의 스크립트에대하여 설명하면서 대표적인 예로 레이어를 자동으로 저장하는 기능을 설명드린 적이 있는데요. 이번에는 좀더 간단한 ( 코딩 줄 수가 짧은 ) 스크립트로 다시 올려봅니다.

 

A-Z 하나하나 작성 설명을 포함했던 기존 스크립트

https://diy-dev-design.tistory.com/6

 

방식은 동일한데요. 변수나 함수의 정의 방법을 개선하여 대폭 코딩 양을 줄인 케이스 입니다.

 

1. 우선 PSD 파일의 모든 레이어에 대하여 PNG 파일로 저장이 됩니다.

2. 현재 PSD 파일의 경로에 폴더가 생성되고 그 하위에 이미지가 저장됩니다.

3. 저장되는 이미지는 현재 레이어의 이름으로 저장 됩니다.

4. 레이어 내에 폴더(레이어셋)가 있는경우 하위폴더가 해당 레이어 셋 이름으로 생성되고

5. 레이어 셋 내의 레이어 들은 그 하위 폴더 내부에 저장됩니다. 포토샵 구조와 동일하게 저장되죠.

6. 저장되는 파일은 PNG 파일로 저장이 됩니다. 

var pngOption = new PNGSaveOptions()
    pngOption.embedColorProfile = true;
    pngOption.formatOptions = FormatOptions.STANDARDBASELINE;
    pngOption.matte = MatteType.NONE;
    pngOption.quality = 100;
    pngOption.PNG8 = false; //24 bit PNG
    pngOption.transparency = true;
    pngOption.interlaced = true;

var cDoc = app.activeDocument
var tempLayers = cDoc.layers
var cWidth = cDoc.width
var cHeight = cDoc.height
var cRes = cDoc.resolution
var savePath = cDoc.path + "\\"

// 일단 모든 레이어를 꺼줍니다.
for (var i = 0 ; i < tempLayers.length; i++)
{
	tempLayers[i].visible = false
}

// 아래의 한줄의 함수로 모든 레이어를 저장합니다.
explorerLayerSet_new(savePath, cDoc) 

function explorerLayerSet_new (cPath, lSet){
	var dLyrs = lSet.layers
	for (var k = 0 ; k < dLyrs.length; k++){
		if (dLyrs[k].typename == "LayerSet") 
		{
			dLyrs[k].visible = true
			ePathName = cPath + dLyrs[k].name + "\\"
			ee = new Folder(ePathName)
			ee.create();
			explorerLayerSet_new (ePathName, dLyrs[k])
			dLyrs[k].visible = false
		}else{
			dLyrs[k].visible = true
			dFile = File(cPath + dLyrs[k].name + ".png")
			cDoc.saveAs(dFile, pngOption,true, Extension.LOWERCASE)  
			if (dLyrs[k].name.indexOf("All") == -1)
			{
				dLyrs[k].visible = false
			}
		}
	}
	lSet.visible = false
}

 

네.. 많이 짧아 졌습니다.

 

일단 재귀함수 (반복해서 하위로 탐색해나가는 함수) 부분에 변수를 정의할 때 var 라는 지시어를 붙여 주어 로컬 변수가 될 수 있도록 하여 재귀 호출시에 문제가 없도록 변경한 것이 기존 대비 가장 큰 차이점이라 할 수 있겠습니다.

 

번거롭게 코딩하는 것이 귀찮으시면 위의 내용을 메모장에다가 붙여넣으신 다음 확장자를 jsx 로 하여 저장한뒤 사용하시면 되겠습니다.

 

포토샵에 기본적으로 들어있는 Layer Export 스크립트 보다 빠르고 하위 폴더까지 저장되므로 PSD 자료 정리에 편리하게 사용하시기 바랍니다.

 

포토샵에서 기존에 만들어진 스크립트를 사용하는 방법은 아래 포스트를 참고하세요~

https://diy-dev-design.tistory.com/47

 

[포토샵스크립트] 스크립트 단축키로 실행하기

안녕하세요. 오늘은 자신이 작성하였거나 웹에서 다운로드 받은 스크립트를 간단하고 빠르게 실행하는 방법을 알려드리겠습니다. 우선 스크립트를 실행하는 방법은 몇가지가 있는데 다음과 같습니다. Extend Scrip..

diy-dev-design.tistory.com

 

2019-09-10 내용을 추가합니다. : JPG 저장 옵션

기존 만들어진 스크립트에 jpg 파일로 저장하기 위한 옵션이 따로 있으면 좋을 것 같아서 jpg 파일 저장 옵션을 추가하였습니다. 아래 몇줄을 추가하고 나면 스크립트 초반에 저장하고 싶은 옵션을 골라 저장을 할 수 있습니다.

var pngOption = new PNGSaveOptions()
    pngOption.embedColorProfile = true;
    pngOption.formatOptions = FormatOptions.STANDARDBASELINE;
    pngOption.matte = MatteType.NONE;
    pngOption.quality = 100;
    pngOption.PNG8 = false; //24 bit PNG
    pngOption.transparency = true;
    pngOption.interlaced = true;

// jpg 파일 저장을 위한 설정
var jpgSaveOption = new JPEGSaveOptions()
    jpgSaveOption.quality = 8;
    
var sType = "jpg" // jpg 로 파일을 저장하기를 원하는경우, png 로 저장을 하고 싶다면 "png"
var cDoc = app.activeDocument
var tempLayers = cDoc.layers
var cWidth = cDoc.width
var cHeight = cDoc.height
var cRes = cDoc.resolution
var savePath = cDoc.path + "\\"

// 일단 모든 레이어를 꺼줍니다.
for (var i = 0 ; i < tempLayers.length; i++)
{
	tempLayers[i].visible = false
}

// 아래의 한줄의 함수로 모든 레이어를 저장합니다.
explorerLayerSet_new(savePath, cDoc) 

function explorerLayerSet_new (cPath, lSet){
	var dLyrs = lSet.layers
	for (var k = 0 ; k < dLyrs.length; k++){
		if (dLyrs[k].typename == "LayerSet") 
		{
			dLyrs[k].visible = true
			ePathName = cPath + dLyrs[k].name + "\\"
			ee = new Folder(ePathName)
			ee.create();
			explorerLayerSet_new (ePathName, dLyrs[k])
			dLyrs[k].visible = false
		}else{
			dLyrs[k].visible = true
			dFile = File(cPath + dLyrs[k].name + "." + sType)
            
              if (sType == "jpg") // jpg 로 저장을 하는 경우를 판단함
              {
                  cDoc.saveAs(dFile, jpgSaveOption,true, Extension.LOWERCASE)  
              }else{
                  cDoc.saveAs(dFile, pngOption,true, Extension.LOWERCASE)  
              }
			
			if (dLyrs[k].name.indexOf("All") == -1)
			{
				dLyrs[k].visible = false
			}
		}
	}
	lSet.visible = false
}

 

2019-12-04 일반 사용자 분들도 쉽게 사용하실 수 있도록 스크립트를 첨부하였습니다.

아래 링크에서 다운로드 받으셔서 사용하시면 됩니다.

레이어 저장이 필요한 PSD 파일을 열어두신 후 다운로드 받으신 jsx 파일을 드래그 해서 포토샵 바탕위치로 드롭하면 스크립트가 자동으로 실행이 되며 이미지가 저장이 됩니다. (PSD 이미지 위가 아닙니다. 포토샵의 검정색 배경 부분에 가져다 놓으셔야 합니다)

layerexporter.jsx
0.00MB

 

2019-09-10 내용을 추가합니다. 레이어 저장시 레이어의 크기로 저장되도록 기능 추가

아래 포스트에서 확인 하시면 됩니다. 거의 비슷한데요. 레이어별 크기로 저장을 하거나 기존 도큐먼트 사이즈로 저장할 수도 있습니다.

https://diy-dev-design.tistory.com/72

 

[포토샵스크립트] PSD 모든 레이어 자동 저장, 하위 폴더 포함 (레이어 크기로 이미지 저장)

안녕하세요. 제가 포토샵 스크립트를 이용하여 PSD 파일내의 모든 레이어를 자동으로 하위폴더 구조를 유지하며 저장할 수 있는 스크립트를 만들어서 올렸었는데요. 바로 아래 링크에서요. https://diy-dev-design..

diy-dev-design.tistory.com

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

궁금하신 부분이 있다면 뎃글로 문의 해 주세요~

반응형
반응형

얼마뒤면 베트남으로 가족 여행을 떠날 예정입니다. 7박이나 하고 올 예정이므로 집을 비우기 전 준비해야 할 것들이 많습니다. 이것저것 여행준비를 하던 찰나 베란다에 내어 둔 화분이 걱정이 되었습니다. 출발하기 전에 물을 듬뿍 주고 간들 요즘처럼 더운 날씨에 화분이 마르는건 금방이지요. 아마 이틀이면 마르지 않을까 싶습니다. 7일뒤에 돌아왔을때 딸내미가 애지중지 물을 주던 나팔꽃이 매말라 버릴까 걱정이 되었습니다. 그래서 부랴부랴 있는 부품을 찾아 모아 간단하게 자동으로 물을 주는 시스템을 만들어 보았습니다.

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

 

제 작업실에서 주워 모은 부품은 아래와 같습니다.

 

사용된 부품 리스트

토양 수분 측정 센서 

초소형 DC 모터 펌프 (3V)

아두이노 나노

drv8833 DC 모터 드라이버

링거 줄 

T 형 분배 소켓

소형 방열판 (전자제품 분해하면서 떼어냈던 것)

대형 식초 병 (코스트코에서 샀던 식초, 4L )

 

화분 물주기 시스템을 만들기 위하여 필요한 부품들

 

집에 이런것들이 왜 있나 싶지만 저처럼 DIY 를 좋아하는 사람이라면 알리익스프레스 눈팅하면서 하나둘 사모은 부품들이 있게 마련입니다. 토양 수분 측정 센서는 수위 센서라고도 하는데 언젠가 한번은 사용하겠지 싶어 사두었고 DC 모터 펌프는 물고기 수조에 공기 공급을 위하여 구입했던 부품이었습니다. DRV8833 모터 드라이버가 좀 특이한데 RC 카 만들어 보겠다면서 구입했던 보드였습니다. 

 

원리는 간단합니다.

 

토양 수분 센서를 통해 토양의 습도를 측정한뒤 일정 값 미만으로 내려가게 되면 아두이노는 DC 모터드라이버로 모터를 동작시키도록 신호를 보냅니다. 모터가 동작되면 펌프는 물을 끌어올려 화분에 뿌리게 됩니다. 화분의 흙이 일정 수준 이상 젖게 되면 센서 값에 의해 모터가 멈추게 되는 방식 입니다. 

 

이렇게 해두면 며칠을 비워도 문제가 없을 것입니다. 물론 물통이 4L 이므로 그 물이 다 소진될때 까지 비우면 안되겠지만요.

 

배선은 아래와 같이 하면 됩니다.

 

토양 수분 센서

  • GND : GND
  • VCC : VCC (5V)
  • AO : 아두이노 A0 핀
  • DO : 연결 안함

 

DRV8833

  • GND : GND
  • VCC : VCC (5V)
  • IN1 : 아두이노 9번 핀 (PWM 이 출력되지요)
  • IN2 : GND (코드에서는 10번에 연결하는것이 맞지만 최종 적으로 한쪽 방향으로만 돌릴꺼라서 그냥 GND 에 연결)
  • OUT1 : motor +
  • OUT2 : motor -

그림은 나중에 다시 올리도록 하겠습니다.

 

 

 

먼저 간단하게 아두이노 코드를 작성해 보았습니다. 별도의 라이브러리 없이 간단히 작성이 가능합니다.

 

int soilPin = A0;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
    int value = analogRead(soilPin);

    if (value > 800)
    {
      analogWrite(9, 128);
      digitalWrite(10, LOW);
    }else{
      digitalWrite(9, LOW);
      digitalWrite(10, LOW);
    
    }
    
    Serial.print("read sensor value : ");
    Serial.println(value);

    delay(600000); // 10분에 한번 체크하는 것으로 수정하였습니다.
}

토양 센서로 부터 받는 신호는 A0 번 핀을 통해 전달받으며 코드상에서는 analogRead 라는 명령어로 입력 받습니다. 테스트를 해보니 해당 센서는 흙속의 수분에 의해 전기 전도가 이루어 지고 이 정도를 파악하는 센서인데요. 공기중에 노출시킨상태, 즉 토양이 완전히 마른상태에서는 1023 의 값을 출력하고요, 물에 담갔을 때, 즉 완전히 젖은 상태에서는 200 미만의 값이 출력이 되는 것을 확인하였습니다. (아마 물 속의 전해질의 농도에 따라서 최소 값은 차이가 있을 것 같았습니다)

 

저는 완전히 마를때 까지 둘 것이 아니었으므로 800 이라는 값보다 커지게 되면 모터를 동작하도록 한 것이죠.

 

DRV8833 으로는 PWM 신호를 보내서 모터의 속도를 제어할 수 있습니다. 두개의 모터를 각각 제어할 수 있는데요 IN1, IN2 를 통해 하나의 모터를, IN3 IN4 를 통해 다른 하나의 모터를 제어할 수 있습니다. 4개의 모터에 대하여 정방향, 역방향으로 각각 속도를 제어하기 위하여는 4개의 PWM 이 필요한데 만약 저처럼 단방향으로만 제어한다면 모터당 1개의 PWM 만 있으면됩니다.

 

IN1 : PWM / IN2 : GND --> 정방향 회전 (속도는 PWM에 따라)

IN1 : GND / IN2 : PWM --> 역방향 회전 (속도는 PWM에 따라)

IN1 : GND / IN2 : GND --> 정지

 

이런식으로 제어를 하시면 되겠습니다. 

 

위에 코드를 보시면 하나의 핀을 PWM 출력도 하고 GND 로 하기도 하는 코드가 있습니다.

 

저는 5V 를 전원으로 사용하고 모터의 정격 전압이 3V 이므로 PWM 은 안전빵으로 128을 출력하였습니다. 실제 모터에 몇 V 가 인가되는지는 확인하지는 않았으나 별다른 무리 없이 잘 동작 되었습니다.

참고로 DRV8833 으로 입력하는 전원은 모터가 워낙 작고 저전력을 사용하므로 그냥 아두이노의 5V 출력을 이용했습니다. (참고로 모터 구동은 왠만하면 별도의 전원을 사용하는 것이 좋고 노이즈 차단을 해주는 것도 좋습니다)

 

 

그럼 설치가 완료된 사진을 보시겠습니다

 

물주기 시스템 장착된 작은 화분, 나팔꽃과 수박, 참외가 자라고 있다.

 

알리익스프레스에서 2000 원 정도 주고 구입한 작은 펌프. N20 모터가 달려있다.

동작해보니 모터에서 열이 조금 나는 것이 느껴져 방열판을 하나 달아 주었습니다. 버리는 전자제품을 뜯어 보면 저런 방열판이 흔히 발견되므로 보는 족족 적출하여 보관하는 습관을 가집시다.

 

토양 수분 센서를 화분에 꼽아 주었다.
좌측이 아두이노 나노, 가운데가 DRV8833, 우측은 토양 수분 센서와 연결된 보드
전체 모습이다. 좀 지저분 하지만 1주일 뒤에 철거 할 예정이므로 적당히...

이렇게 해서 설치가 모두 완료 되었습니다. 내일 모레 출발 전에 물은 다시 한통 가득 채워놓을 예정입니다.

설치된 모습이 좀 지저분 하기는 하지만 1주일 뒤 귀국하면 다시 치울 예정이므로 적당히 저렇게 두기로 합니다. 물도 물이지만 18650 배터리 2개를 직렬로 연결하여 두었는데 과연 1주일을 버틸지는 의문입니다. 내일이라도 아답터를 연결해 놓는것이 좋을까요... 

 

암튼 아주 간단하게 자동으로 화분이 마르지 않도록 물을 주는 시스템을 만들어 보았습니다.

 

사실 시골에서 밭농사라도 한다면 밭의 수분 측정 및 자동으로 물 주는 시스템은 요긴하게 사용될수 있는 시스템입니다. 작은 태양광 전지, NRF24L01 같은 무선 송수신 장치, 스프링클러 등을 이용하면 시골의 밭에서 자동으로 경작지에 물을 줄 수 있는 시스템을 손쉽게 만들 수 있을 것 입니다. 간단한 노력으로 쓸모있는 스마트 팜을 만들어 가실 수 있는 것이죠.

 

이상 자동으로 화분에 물주기 장치 만들기였습니다.

 

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

 

궁금하신 것은 뎃글로~ 재밌으셨거나 도움이 되셨으면 공감 부탁드립니다.

 

이 시스템은 이후 수경재배용 장치를 만드는데 거의 동일하게 사용되었습니다.

https://diy-dev-design.tistory.com/60

 

[DIY] 아두이노를 이용한 수경재배 시스템

아두이노는 정말 놀라운 하드웨어가 아닐수 없죠. 우리가 생각하는 이런건 자동으로 해주는거 없나? 이런게 자동으로 되면 좋을텐데... 이런걸 왜 자동으로 안하는거야?? 같은 대부분의 자동화 장치, 기계장치를..

diy-dev-design.tistory.com

 

20191206 내용 추가

저와 동일한 센서 또는 유사한 센서를 이용하시는 분들께 안내 말씀을 드립니다.

해당 센서를 이용하였을 경우 센서의 표면의 부식이 상당히 빠르게 진행이 됩니다. 진작에 올렸어야 하는데 깜박하고 있었네요. 

아마 한쪽 핀에서 다른쪽 핀으로 전기 신호를 보내서 도착하는 전류량을 측정하는 듯한데요. 이런 과정에서 금속 표면이 부식이 되는 문제가 있었습니다. 제 생각으로는 센서로 보내는 신호를 상시 측정 하지 마시고 한시간에 한번 또는 하루에 한번 정도씩 측정 주기를 늘려주어 절대적인 전류 측정 시간을 줄여주는 것이 좋을 것 같습니다.

토양의 수분이 매순간 측정해야 할 만큼 빠르게 변하는 요소는 아니기에 측정의 인터벌을 길게 잡아주면 센서의 부식을 막고 좀더 오래 사용이 가능할 것으로 판단 됩니다.

 

 

 

자동으로 텃밭(화단) 물주기 장치

여러분들 집에는 작은 텃밭 하나씩 있으신가요? 저는 없습니다만 처갓집에는 작은 비닐 하우스와 텃밭이 있습니다. 요즘처럼 날씨가 가물거나 하우스 안에 텃밭을 가지고 계신 분들은 매일매일

diy-dev-design.tistory.com

 

 

[DIY] micro:bit - 병아리 부화기 만들어 보기 (초딩도 가능)

딸내미 : "아빠! 할머니 집에서 가져오는 계란은 유정란이야?" 나 : "그럼~. 암탉도 있고 수탉도 있으니 유정란이겠지?" 딸내미 : "그럼 내가 저거 품으면 병아리가 나오는 거야?" 나 : "흠... 아니....

diy-dev-design.tistory.com

 

 

0.96 inch OLED 디스플레이 구동하기

가끔 아두이노로 무엇인가를 만들어 보려고 하다보면 디스플레이가 있으면 하는 생각이 들때가 있습니다. 아두이노는 작은 컴퓨터이기는 하지만 모름지기 컴퓨터라 한다면 입력장치 - 중앙처��

diy-dev-design.tistory.com

 

 

미니 테슬라코일 만들기 - 알리 DIY KIT

어렸을적 위대한 발명가, 과학자 하면 단연 손꼽는 일인자가 있었는데 누군가 물어본다면 100 이면 100 다 토마스 에디슨을 떠올릴 것입니다.. 그런데 커보니 에디슨은 발명가나 과학자라기보다��

diy-dev-design.tistory.com

 

 

Arduino(아두이노) 무작정 시작하기

아두이노, Arduino 여기저기서 많이 들었을 겁니다. 이걸 해야 된다는 말이 귀에 못이 박히도록 이야기 합니다. 대충 뭔지는 알겠는데 개발자도 아닌 내가 과연 이걸로 뭘 할 수 있을까 싶기도 하��

diy-dev-design.tistory.com

 

 

C# 에서 아두이노로 시리얼 통신 하기

카테고리를 c# 으로 해야 할지 Arduino 로 해야할지 조금 고민이 되는 포스트 입니다. 음.... arduino 로 하는게 좋겠네요. 따지고 보면 C# 으로 만든 어플이 중요한게 아니라 아두에노에서 시리얼 통신

diy-dev-design.tistory.com

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 만능 (통합) 리모콘 만들기 1/3

2019/11/10 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 2/3

2020/06/17 - [DIY/Arduino] - [DIY] 아두이노로 통합(만능) 리모콘 만들기 3/3

반응형
반응형

집에 우쿨렐레가 두개가 있어 따로 거치대를 만들었었는데 이게 바닥에 놓는 형식이다 보니 두대를 놓고나면 이래저리 자리를 많이 차지하여 여간 불편한게 아니었습니다.

 

그래서 이번에 우쿨렐레 거치대를 새로 만들었는데 얼마전에 구입한 3D PEN 을 이용하여 만들면 재미있을 것 같아 제작을 해보았습니다.

 

먼저 도면을 아래와 같이 그려보았습니다. 일러스트레이터를 이용해 도면을 쓱삭쓱삭.

 

 

벽에 부착하는 부분은 나무로 제작하고 위에 검은 색 부분이 우쿨렐레가 걸리는 부분으로 3D Pen 을 이용하여 제작할 부분이 되겠습니다. 아래 테두리만 있는 부분이 실제 제작할 크기로 확대 해 놓은 도면입니다.

 

3D Pen 은 3D 프린터와 달리 빠르게 조형이 가능하다는 장점이 있고 또 정밀하지는 않지만 삐뚤뻬뚤한 뭔가 아날로그한 맛이 있는것이 장점이라 할 수 있겠습니다. (장점인지, 단점인지는 생각하기 나름)

 

 

집에 있는 프린터를 이용하여 간단하게 뽑아보았습니다. (프린터는 브라더 프린터를 사용하고 있습니다)

 

출력한 종이에 대고 3D Pen 을 이용하여 그려나가면 됩니다. 테두리를 먼저 그리고 안쪽을 채워나가는 순서로 제작하게 되는데 3D 프린터 역시 동일한 방법으로 프린팅을 진행합니다. 

 

먼저 한조각을 만들어 보았습니다. 필라멘트는 ABS 로 PLA 에 비하여 강도가 높고 제작 후 변형이 적습니다. 물론 온도나 습도에도 더 강한 면을 보여줍니다. PLA 의 경우 강도가 약해 무거운 힘을 받거나 하면 부러져 버리는 경우가 있지만 친환경 재료이며 제작하는 동안 고약한 냄새가 나지 않아 많이들 사용하고 있지요. 물론 제작하는 동안 수축도 적어 비교적 정확한 모형을 만드는 것이 가능합니다. 

 

시꺼먼 선들이 저렇게 있으니 뭔가 베놈 같아요.

 

좀더 층을 올린 후 마무리를 하고 우쿨렐레가 두개이므로 하나를 더 만들어 보았습니다. 

 

중심부로 나사못이 관통해야 하므로 중심부는 약간 더 두껍게 만들어 주었습니다.

 

 

 

 

벽에 고정할 나무를 먼저 붙여주고 그다음에 출력한 플라스틱 부분을 붙일 계획입니다.

 

아래는 나무 토막을 붙인 모습

 

가운데 구멍에 출력한 플라스틱 부분을 부착하게 됩니다.

 

바로 요렇게.

 

 

다른 각도에서 본 모습

 

 

우쿨렐레를 걸어보았습니다. 위아래로 나란히 걸수 있도록 두개를 부착해 주었습니다.

우쿨렐레의 무게가 워낙 얼마 되지 않기 때문에 떨어지거나 부러질 염려는 없어보이는데 걸고 꺼낼때 심하게 아래로 당기면 파손이 될수도 있겠다는 생각은 듭니다.

 

 

그리하여 기타1, 우쿨렐레 2가 적당한 공간에 보기좋게 위치할 수 있게 되었습니다.

 

 

 

 

3D Pen 을 사용하여 무엇인가를 만드는 것도 매우 흥미롭고 즐거운 일입니다. 내 손에 의해 무엇인가가 창조되는 느낌?

 

참고로 ABS 는 플라스틱 타는 냄새가 좀 나므로 환기가 잘되는 환경에서 작업을 할 필요가 있다고 생각됩니다.

 

그럼 이만~

 

 

 

반응형
반응형

이미지 관련된 툴을 개발함에 있어 다양한 이미지 포멧을 만들고 변경하기 위한 코어를 개발하는 것은 말도 안되게 힘든 작업입니다. 저는 디자이너라는 타이틀을 가지고 있기 때문에 포토샵이라는 훌륭한 어플리케이션이 기본적으로 설치가 되어 있어 간단한 스크립트 만으로 다양한 이미지 컨트롤을 할 수 있지만 개발자 또는 일반인이 포토샵을 구해서 사용하려면 비용적인 부담이 있기 때문에 망설여 질 수 밖에 없습니다.

 

물론 Irfanview 와 같이 무료이면서 아주 다양한 기능을 지원하는 이미지 뷰어도 있습니다만 어떤 목적에 맞게 개발적 관점에서 이미지를 변경할 수 있는 툴이 필요한 경우도 있게 마련입니다.

 

그런 경우 아주 적합한 툴이 바로 ImageMagick 입니다. 아래는 해당 Application의 홈페이지 입니다.

https://imagemagick.org/index.php

 

ImageMagick

Create, Edit, Compose, or Convert Bitmap Images

imagemagick.org

 

가보면 다운로드 받아 PC 에 설치하고 간단한 커맨드 명령만으로 이미지를 변환 할 수 있다는 것을 알 수 있습니다. 간단하게는 사이즈를 변경하거나 이미지의 포멧을 바꾸거나 하는 것을 할수 있고 주석을 넣거나 이미지의 뎁스를 변경하거나 여러장의 이미지를 합성하는 등의 복잡한 기능도 커멘드 라인을 통해 진행할 수 있습니다.

 

하지만 이번 글 제목처럼 단순 이미지 변경외에도 전체적인 개발 과정에서 이미지 변환이 필요하거나 복잡한 로직속에 이미지 수정이 필요하여 해당 툴을 사용해야 하는 경우 C# 에서 DLL 을 불러들여 개발을 하는 방법이 있습니다. VS 2017 이상이라면 아주 간단합니다.

 

먼저 비주얼 스튜디오의 상단 도구 메뉴에서 도구 --> Nuget 패키지관리자 --> 솔루션용 Nuget Pakage 관리.. 를 선택해 줍니다.

 

위와 같이 찾아보기 텝에서 검색창에 ImageMagick 을 적어 줍니다.

그러면 아래에 검색된 결과가 나오는데요. 저는 .NET 용 패키지를 설치하려고 합니다. 리스트를 내려볼까요.

 

요런 식으로 Magick.NET 이라고 붙어 있는 녀석이 .NET 용 라이브러리 입니다.

저는 Q8-x64 를 설치할 예정입니다. Q8 과 Q16 이 있는데 Q8 이 컨트롤이 좀더 심플합니다. 기회가 되면 나중에 설명을 드리겠습니다.

 

 

Q8-x64 를 선택하고 나면 우측에 비어있던 창에 아래와 같이 나타납니다.

현재 프로젝트 명이 체크박스와 함께 나타나는데요. 

현재 프로젝트 명 앞의 체크박스를 선택해주면 아래 "설치" 라는 버튼이 활성화 됩니다.

 

설치버튼을 누르고 새로 뜨는 팝업창에서 확인버튼을 하번더 눌러주면 dll 설치가 끝이 납니다.

 

다시 코드로 와서 상단에 using 으로 시작하는 지시문을 추가해줍니다.

 

using ImageMagick;

 

이제 코딩을 할 준비는 모두 끝이 났습니다. 

 

다음 포스트에서 ImageMagick 을 이용하여 이미지를 컨트롤 하는 방법을 올려보도록 하겠습니다.

 

궁금한 것은 뎃글 주세요.

 

도움이 되셨다면 공감도 꾹 부탁합니다.

2020/06/03 - [DEV/c#] - C# .net으로 photoshop 연동하기

 

C# .net으로 photoshop 연동하기

저는 회사에서 디자인팀에 있고 전공도 디자인과 출신이며 심지어는 고등학교도 예체능계열 고등학교를 나왔습니다만 지금 회사에서 하는일의 95% 정도는 개발을 하고 있습니다. 실제로 제가 ��

diy-dev-design.tistory.com

2020/04/03 - [DEV/c#] - ImageMagick 을 이용하여 이미지 컨트롤 해보기

 

ImageMagick 을 이용하여 이미지 컨트롤 해보기

포토샵 없이 이미지를 편집하는 방법이 없을까 고민하다가 알게된 라이브러리, 바로 ImageMagick 입니다. 먼저 포스트에서 ImageMagick 을 프로젝트에 가져오는 방법을 아래와 같이 소개해 드린적이 ��

diy-dev-design.tistory.com

 

2020/01/03 - [DEV/c#] - [C#] C# APP 에서 엑셀 연동해보기

 

[C#] C# APP 에서 엑셀 연동해보기

엑셀에서 VBA 로 코드를 짜다 보면 막상 특정 엑셀 파일에만 VBA 가 적용이 가능하기 때문에 막상 다른 엑셀 파일에서 동일한 동작을 하려면 또 코드를 복사해 넣고 실행을 해야 하는 경우가 있습�

diy-dev-design.tistory.com

 

 

 

 

 

반응형
반응형

사용자의 마우스 컨트롤 없이 자동으로 지정된 위치에서 마우스를 클릭하게 만들어 주는 기능 입니다.

 

먼저 아래와 같이 DLL 을 불러들여 주어야 하겠습니다.

class 정의 바로 아래부분에 넣어 주면 무난하겠네요.

[DllImport("user32.dll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);

[DllImport("user32")]
public static extern int SetCursorPos(int x, int y);

 

DllImport 부분에 빨간 줄이 나온다면 제일 상단에 아래의 같이 지시문을 추가합니다

 

using System.Runtime.InteropServices;
using System.Threading;

<2022/12/28 누락된 코드가 있어 추가하였습니다>

그런 다음 마우스를 이동하는 함수를 만들어야 겠습니다.

 

먼저 상수값을 지정해 주어야 합니다. 마우스의 각 이벤트에 대응되는 상수인데요. 이름은 적당히 적어 주면 됩니다.

역시 Form 상단 클래스 정의 이후에 아래와 같이 정의해주면 되겠습니다.

private const int MouseEV_Move = 0x0001; 		/* mouse move 			*/
private const int MouseEV_LeftDown = 0x0002; 	/* left button down 	*/
private const int MouseEV_LeftUp = 0x0004; 	/* left button up 		*/
private const int MouseEV_RightDown = 0x0008; 	/* right button down 	*/

private int interval_;
private readonly ManualResetEvent stoppeing_event_ = new ManualResetEvent(false); //System.Threading;

<2022/12/28 누락된 코드가 있어 추가하였습니다>

그런 다음 아래에 실제 함수를 작성해 봅니다.

public void MouseSetPosNclick(int x, int y)
{
	try
	{
		SetCursorPos(x, y);
		stoppeing_event_.WaitOne(interval_);
		MouseClick_now();
	}
	catch (Exception e)
	{
		MessageBox.Show("MouseSetPosNclick\r\n" + e.Message);
	}
}

public void MouseClick_now()
{
	try
	{
		mouse_event(MouseEV_LeftDown, 0, 0, 0, 0);
		mouse_event(MouseEV_LeftUp, 0, 0, 0, 0);
		stoppeing_event_.WaitOne(100);
	}
	catch (Exception e)
	{
		MessageBox.Show("MouseClick_now\r\n" + e.Message);
	}
}

 

 

사용하실 때에는 아래와 같이 사용하시면 되겠습니다.

 

MouseSetPosNclick(467, 280); // 원하는 좌표를 입력하면 됩니다.

 

궁금하신 부분은 뎃글로 질문 남겨 주세요~

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

 

 

본 기능을 이용하여 윈도우 잠금 방지 유틸리티를 하나 만들어 보았습니다.

https://diy-dev-design.tistory.com/98

 

재택근무 필수 유틸 "자리안비움" - 윈도우 꺼짐 방지

요즘 코로나 바이러스 때문인지 덕분인지 재택근무를 하는 분들이 많은데요. 막상 집에 있다 보면 사무실에 있을 때 처럼 연속해서 자리에 머무르지 못하는 경우가 종종 있습니다. 애들이나 와이프가 뭐 부탁하면..

diy-dev-design.tistory.com

 

2020/07/21 - [DEV/c#] - C# 문자열 읽어서 문자열에 해당하는 변수에 값 세팅하기

 

C# 문자열 읽어서 문자열에 해당하는 변수에 값 세팅하기

오늘 소개해드릴 꿀팁은요. 문자열을 읽어 들여서 문자열 내에 들어있는 특정 단어를 이용하여 개발 중인 코드의 변수로 인식하여 해당 변수에 값을 세팅하는 방법을 소개해 드릴까 합니다. 예�

diy-dev-design.tistory.com

2023.01.31 - [DEV/c#] - [c#] Resource 에 추가한 텍스트를 소스코드에서 불러오기

 

[c#] Resource 에 추가한 텍스트를 소스코드에서 불러오기

뻔하디 뻔한 개발 노하누는 가라~ 이번에도 쓸만한 내용을 소개해 드릴 까 합니다. 개발을 하다 보면 실제 소스코드 외에도 어떤 텍스트를 resource 에 넣어 두고 소스코드에서 불러와야 하는 경우

diy-dev-design.tistory.com

 

반응형
반응형

 

c# .net 환경 개발시 아래의 함수를 이용하여 Delay 를 구현할 수 있습니다.

 

private static DateTime Delay(int MS)
{
  DateTime ThisMoment = DateTime.Now;
  TimeSpan duration = new TimeSpan(0, 0, 0, 0, MS);
  DateTime AfterWards = ThisMoment.Add(duration);

  while (AfterWards >= ThisMoment)
  {
    System.Windows.Forms.Application.DoEvents();
    ThisMoment = DateTime.Now;
  }

  return DateTime.Now;
}

 

사용할때는 아래와 같이 사용합니다.

 

Delay(1000); // 1초 동안 Delay 를 하게 되죠

 

이상 간단하게 Delay 기능 사용하기 였습니다.

반응형
반응형

화장실 환풍기를 통해 우리집 나쁜냄새가 빠져 나가는 것은 정말 훌륭한 기능입니다. 화장실이란 공간 자체가 대부분 밀폐되어 있기 때문에 냄새가 빠지지 않으면 사용하기 않좋은 공간이죠.

 

그런데 저희집에 커다란 문제가 생겼습니다. 바로 얼마 전부터 심각하게 담배 냄새가 밀려 들어오는 일이 일어 난 것이죠. 연초를 끊고 액상형 전자담배를, 그것도 향도 없는 전자 담배를 피는 제게는 매우 큰 스트레스가 아닐 수 없었습니다. 와이프와 아이들에게도 역시나 큰 스트레스였죠.

 

한동안은 욕실 문을 닫아 놓고 살았습니다. 그런데 욕실 문이 밀폐가 되는 것이 아니고 또 욕실을 아예 사용하지 않을 것도 아니었기 때문에 사용하려고 들어가면 담배냄새때문에 속이 울렁거릴 정도였습니다. 담배를 피는 사람은 그 느낌을 모르죠. 

 

엘레베이터에도 담배 냄새로 호소하는 글이 매일 같이 붙어 있었지만 소용이 없었습니다.

 

어떤 커뮤니티에서 보니 담배 피는 사람은 '내집에서  내가 담배 피는데 대체 무슨 상관이냐' 라는 논조였고 '그 연기가 그쪽 집으로 간것은 건물에 하자가 있으니 건물주에게 항의해라' 라는 식인 분들이 생각보다 꽤 되더라구요. 이해할 수는 없었지만 그래도 그런사람들이 있는 마당에 말해봐야 싸움만 일어날게 뻔 하다는 생각이 들었습니다.

 

인터넷을 알아보던 중 알게된 사실과 제가 선택한 솔루션을 공유해 드리겠습니다.

 

일단 욕실 천정형 환풍기에 구조적으로 역류 방지 댐퍼가 장착이 되어 있는 제품이 있습니다. 가능하면 해당 댐퍼가 있는 제품을 사용하는 것이 좋겠습니다. 하지만 댐퍼가 밀폐 되지 않고 단순히 플라스틱 덮개 수준이라면? 당연히 냄새가 새어 들어오겠죠.

 

만약 욕실로 담배 냄새가 심하게 밀려 들어온다면 댐퍼의 유무를 반드시 확인해 보셔야 할 것 같습니다.

 

댐퍼가 있는데도 단순 플라스틱 덮개로 되어 있어 냄새 차단이 되지 않는 다면 저처럼 확실한 솔루션이 필요한 상황인 것 같습니다.

 

저는 온라인 쇼핑몰에서 스멜스탑이라는 제품을 구입하여 설치하였습니다. (광고글 아님)

 

 

기존 환충기의 출기구 부분에 장착을 하고 댐퍼의 출기구 쪽에 다시 에어가 나가는 관을 연결해주는 형태인데요. 뎀퍼 역할을 하는 막이 플라스틱이 아닌 실리콘 형태 입니다. 아주 얇고 부드러운 재질이어서 화장실 쪽에서 바람을 밀어주면 댐퍼가 열렸다가 외부에서 공기가 들어오려 하면 막아주는 방식입니다. 

 

이 제품의 특징이라 하면 뎀퍼가 약간 기울어져 설치가 되어 있어 일반 적인 상황에서 외부 기압이 약하더라도 자동으로 닫히는 형상이 된다는 점 입니다. 

 

아래 그림을 보면 이해가 빠르실 것 같습니다.

 

 

제가 작업한 순서는 아래와 같습니다.

 

1. 욕실 천장의 환풍기 커버를 뜯어낸다. --> 1 자 드라이버를 이용하여 귀퉁이 쪽을 제껴서 벗기면 됩니다.

2. 4군데의 나사를 풀어준다.

3. 환풍기를 살살 당겨서 끌어낸다.

4. 기존에 에어 주름관을 고정해주는 핀의 나사를 풀어준다.

5. 스멜스탑을 장착한다.

  - 이때 스멜스탑의 상단이 위쪽으로 가도록 설치해야 함 (중요)

6. 기존 환풍기와 스멜스탑의 테두리를 동봉된 알루미늄테이프로 감싸서 밀폐한다.

7. 스멜스탑의 출기구 부분에 주름관을 씌워준 후 고정핀을 채운다.

8. 알루미늄 테이프로 다시 밀봉판다.

9. 환풍기를 살살 다시 원위치 시키고  나사를 끼워준다.

10 커버를 씌운다.

 

장착은 그다지 어렵지 않은데 화장실이라는 공간의 협소함과 천장에 메달린 기구에 설치를 해야 한다는 점이 좀 어려운 부분이고요. 약간의 시행착오가 있을 수 있지만 그다지 어려운 작업은 아닙니다.

 

그리고 효과는 아주 좋습니다.

 

설치한 이후로 한번도 담배 냄새가 난다고 느껴본적이 없네요. 아주 만족입니다.

진작에 이런게 있는 것을 왜 몰랐을까요.

 

 

참고로 해당 제품은 주방용 랜지 후드에도 장착이 가능하다고 하니 주망에 음식냄새가 지나치게 유입되는 분들도 사용하실수 있을 것 같습니다.

 

좀 개선이 필요한 부분이 있다면

1. 다양한 크기의 환풍기와의 호환을 염두해 두어서인지 일단 꽉 끼워지는 느낌이 없습니다. 

 - 2~3가지 정도라도 연결구 옵션이 있으면 좋을 것 같습니다.

2. 동봉된 알루미늄 테이프로 매끈하게 밀폐하기가 생각보다 어려웠습니다. 

 

작업을 하며 느낀점은 환풍기를 빼내는 순간 주름관으로 부터 엄청난 바람이 밀려 들어옵니다. 이러니 댐퍼가 없으면 당연히 냄새가 날 수 밖에요. 꼭 필요한 부품인 것 같습니다.

또 한가지는 기존 제품도 댐퍼가 이미 달려있는 제품이었으나 위에 적은 것처럼 플라스틱 덮개여서 사실상 바람이 술술 새어 들어옵니다. 어짜피 기능을 만들거면 실리콘 링 같은 차폐가 가능한 씰이 필요할 것 같습니다. 

뎃글, 공감 은 블로그 작성자에게 큰 힘이 된답니다. 
도움이 되었다 생각되시면 클릭!!  부탁드려요~

 

이상 화장실 냄새 차단기 였습니다.

 

2020/03/16 - [DIY] - 욕실장(싱크대) 경첩 셀프 교체하기 #노하우, #주부도 가능

 

욕실장(싱크대) 경첩 셀프 교체하기 #노하우, #주부도 가능

이사를 하고 보니 집에 손볼곳이 한두군데가 아니었습니다. 이번에는 욕실장 경첩 입니다. 전세로 이사를 하고나니 내 집도 아닌데 뭘 고쳐가면서 살아... 하는 생각도 들지만 막상 지저분하고 비위생적인 환경은..

diy-dev-design.tistory.com

2019/09/24 - [DIY] - [DIY] 물새는 욕실 수전 수리하기 DADA (DD-1471AC)

 

[DIY] 물새는 욕실 수전 수리하기 DADA (DD-1471AC)

똑, 똑, 똑, ... 욕실에서 심상치 않은 소리가 들려온다. 밤만되면 더욱 커지는 그소리.... 일단 들리기 시작하니 더 크게 들리는 듯한 그소리... 난 침대에서 일어나 욕실로 한걸음, 또 한걸음... 난 욕실로 가는..

diy-dev-design.tistory.com

 

반응형
반응형

포토샵 스크립트 역시 다른 개발언어와 마찬가지로 도움말이 있습니다. 레퍼런스라고 해야할까요. 사실 개발자라고 해도 모든 명령어와 프라퍼티, 메소드를 외우고 있을 수는 없기 때문에 잘 만들어진 레퍼런스가 있으면 큰 도움이 됩니다. 레퍼런스가 잘만들어져있는 스크립트 언어로는 대표적으로 3DS MAXscript 가 있을 수 있겠습니다. 정의와 설명, 사용예시까지 나와 있어 초보 개발자 분들께 아주 큰 도움이 되죠. 포토샵 스크립트에서는 Extend Script Tool kit 에서 제공하는 Object Model Viewer 라는 툴을 제공합니다. 포토샵, 일러스트 등의 어도비에서 제공하는 스크립트의 명령어와 각각 클래스의 메소드, 프라퍼티를 알기 쉽게 제공하는데요. 오늘은 해당 툴을 사용하는 방법을 알아 보겠습니다.

 

우선 Extend Script Tool Kit 을 켜신다음 F1 키를 누르거나 help --> Object Model Viewer 를 선택하시면 아래와 같은 창이 표시됩니다.

 

F1 키를 눌러 도움말을 열어본 화면

상단에 검색을 위한 입력칸이 있고요. 우측 Browser 라고 보이는 부분 하단으로 보여지는 부분이 실제 사용되는 부분입니다. Core Java Script 라고 표시된 부분을 눌러보시면 드롭다운 메뉴가 표시가 되며 여기서 도움을 얻을 언어를 선택하면 됩니다. 기본적으로 자바 스크립트에 대한 레퍼런스가 선택이 되어 있습니다.

 

상단 드롭다운 버튼을 이용하여 현재 프로그래밍 중인 application 을 선택해 준다.

드롭다운을 열어보면 현재 제공하고 있는 언어의 목록이 있는데요. 여기서 포토샵을 선택하면 되겠습니다.

 

중간에 세개의 하얀 박스가 있는데요.

 

맨 위에는 개체를 찾아 선택하는 부분

중간은 해당 개체가 클래스인지, 메소드 인지 어떤 정보인지를 알려주는 부분이고요

아래쪽은 위에서 선택된 개체의 메소드와 프라퍼티를 나열해주고 있습니다.

 

개체를 선택한뒤 개체의 메소드나 프라퍼티를 아래쪽에서 선택하면 우측에 선택한 개체에 대한 설명이 표시가 됩니다.

앞에서 공부 했던 도큐먼트의 크기를 찾는 과정에서 사용했던 width 라는 단어는 아래 보시는 바와 같이 설명이 표시가 됩니다. 데이터 타입으로 unitValue 라고 되어 있는데요. 현재 사용자가 설정한 유닛을 기준으로 값이 리턴이 되게 됩니다.

상단의 Class 창에서 Document 를 선택하고 아래 Width 라는 프라퍼티를 선택한 상태

 하단의 하얀 박스에는 그 외에도 엄청나게 많은 항목이 존재하는데 도큐먼트라는 개체가 갖는 다양한 기능이나 속성을 이용할 수 있습니다. 대표적인 예로 저장하기, 닫기, 컬러모드를 변경한다거나 선택영역 정보를 확인한다던가 하는 작업을 할 수 있으며 하얀 부분에 사용할 수 있는 개체와 사용방법이 표시됩니다.

 

예를 들어 도큐먼트를 닫는 액션을 할건데요. 현재 작업한 것을 저장하지 않고 그냥 닫을 겁니다. 

레퍼런스 기준으로 찾아보면 하단에 close 부분이 되겠는데요. 아래와 같이 설명이 나옵니다.

 

선택한 프라퍼티 또는 매서드에 대한 설명이 우측에 나온다.

측 Document 개체 뒤에 .close 라고 적어주고요. 괄호안에 저장 옵션을 설정해 주어야 합니다. 이미지가 수정되면 닫기 작업을 할때 포토샵이 저장할 것인지 물어보죠? 같은거라고 보시면 됩니다. 그런데 우리는 저장 옵션을 모르기 때문에 역시 찾아봐야 합니다.

저 파란섹 SaveOptionsType 부분을 클릭하면 아래와 같이 창이 변경됩니다.

파랗게 표시된 텍스트는 링크가 있음을 의미하며 해당 속성으로 바로 접근할 수 있다

좌측선택 창이 변경이 되었고 우측 상단에 SaveOptionsType 이라는 개체가 표시되고 있죠? 

다시 좌측 아래를 보면 세가지 옵션이 있습니다.

 

대층 읽어보면 

  • 변경사항을 저장하지 않고 
  • 변경사항을 저장할지 물어보고
  • 변경사항을 저장하고

정도가 되겠습니다.

그중 DONOTSAVECHANGES (변경사항을 저장하지 않고)  를 선택해보면 아래와 같이 우측에 표시가 됩니다.

 

'저장하지 않고 닫기' 에 해당되는 DONOTSAVECHANGES 옵션 (대소문자 주의)

 

실제로 작성해야 하는 최종 상태는 우측과 같은 형태입니다.

 

var imgPath = "D:\\images\\audi-a6-allroad-07.jpg"
var imgFile = File(imgPath)

var cDoc = app.open(imgFile)

cDoc.close (SaveOptionsType.DONOTSAVECHANGES)

 

코드로 작성해보면 위와 같은 형태가 되는거죠. 

열자마자 닫는 의미 없는 코드이기는 하지만 중간에 어떤 작업을 넣을 수 있겠습니다. 

물론 저렇게 저장하지 않고 닫을꺼면 의미는 없겠습니다. 

 

var imgPath = "D:\\images\\audi-a6-allroad-07.jpg"
var imgFile = File(imgPath)

var cDoc = app.open(imgFile)

// 뭔가 사용자가 필요한 코드 수행

cDoc.close (SaveOptionsType.SAVECHANGES)

요렇게 하면 이미지를 열어서 필요한 자동화 액션을 하고 저장하면서 닫는 코드가 되겠습니다.

 

 

참고로 어도비에서 제공하는 PDF로 되어있는 레퍼런스도 있으니 사용해 보시기 바랍니다. 상세하게 나와있고 예제로 작성된 스크립트도 약간 있으므로 처음 배우시는 분들께는 도움이 되실 수 있을 것으로 생각됩니다.

https://www.adobe.com/devnet/photoshop/scripting.html

 

Adobe Photoshop Scripting

 

www.adobe.com

궁금하신 부분은 뎃글 부탁드립니다.

 

공감 꾸욱~ 부탁드립니다.

반응형
반응형

일러스트레이터 스크립트로 만들어진 이미지 몇장 올린다.

 

다각형을 화면에 배치한 이미지이며 필요한 경우 마음 껏 사용해도 됨

 

원본 벡터 이미지도 올리니 필요하면 가져가시고 커스터 마이징을 하고 싶으면 따로 연락 주세요.

 

hexagons.ai
1.56MB
rectangles.ai
2.32MB
triangles.ai
2.27MB

단 무단으로 펌하셔서 재배포는 금지 합니다.

 

 

반응형

+ Recent posts