cafe_basics 0.1.51 → 0.1.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cafe_basics.rb +186 -111
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 664038efea4ab22edff62d90296fa46a585afdbcdcddf25c0f583d74d0949299
4
- data.tar.gz: 501f147f6085475e49942e6a1e489dfd9f13d5d203d23444567abb34cd1a6fa9
3
+ metadata.gz: bff9e36488c3054952fb1a1efddfa003d4dee61ca2486a0c18ea572871d6d5c6
4
+ data.tar.gz: 476445e25e0d71fda3cb4918642121515f337d9e9f59592f323cfb1696b3a251
5
5
  SHA512:
6
- metadata.gz: 39cd755984562579ee0f6e9cc1c826a0409afca6fb7495e4a7e8567c145b7f9e5f64b2219723bb8c99682f8aaafd92b912bedd65b01cc712e99a2fb95e06a709
7
- data.tar.gz: 77a54824410ae82c383794eafa81002ed7aedb5d474b6df33eb05f25b138506938f6b7f4a03f475552502051ce38d8cc68d83d3841a6fe2e357f3217f15c3bdd
6
+ metadata.gz: 17fc8f553e4ff891b2ac22e3fb913b938446c2784ff2aad52afa7f306b0217ca7a747cfe0d936756d22149d6e6457ca9f3d5ae376e78430d025d39d6d5c93d25
7
+ data.tar.gz: 3843e6b48a29828279bcafe8e71c0f519a4e6bc1153a2145999ce9c4b335e42cf51f7406738bbecee65ffdc796690a43d58c059c98532b019267ae974183bbaa
data/lib/cafe_basics.rb CHANGED
@@ -2029,83 +2029,111 @@ class Wordpress
2029
2029
 
2030
2030
 
2031
2031
 
2032
- def auto_image(keyword = nil)
2033
- keyword ||= @keyword
2034
- puts "키워드: #{keyword}"
2035
-
2036
- client = HTTPClient.new
2037
- client.default_header = {
2038
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2039
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2040
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2041
- 'Accept-Language' => 'en-US,en;q=0.9',
2042
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2043
- 'X-Requested-With' => 'XMLHttpRequest'
2044
- }
2032
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
2033
+ img = Magick::Image.read(path).first
2034
+ width = img.columns
2035
+ height = img.rows
2045
2036
 
2046
- retry_count = 0
2047
- max_retries = 10
2048
- results = []
2049
2037
 
2050
- begin
2051
- page = rand(1..15)
2052
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2053
- puts "Request URL: #{url}"
2054
- res = client.get(url)
2055
-
2056
- unless res.status == 200
2057
- puts "HTTP Error: #{res.status}"
2058
- raise "HTTP Error"
2059
- end
2060
2038
 
2061
- json = JSON.parse(res.body)
2062
- results = json['results']
2063
- mm = []
2039
+ if height > width
2040
+ min_height = (width * min_crop_ratio).to_i
2041
+ new_height = rand(min_height..width)
2042
+ crop_top = ((height - new_height) / 2.0).round
2064
2043
 
2065
- results.each do |photo|
2066
- full_url = photo.dig('urls', 'full').to_s
2067
- regular_url = photo.dig('urls', 'regular').to_s
2044
+ cropped = img.crop(0, crop_top, width, new_height, true)
2045
+ cropped.write(path)
2068
2046
 
2069
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
2070
- regular_url.include?("1080")
2071
- mm << full_url
2072
- end
2073
- end
2047
+
2048
+ else
2049
+
2050
+ end
2051
+ end
2074
2052
 
2075
- if mm.empty?
2076
- raise "No matching image"
2077
- end
2053
+ def auto_image(keyword = nil)
2054
+ # auto_image 내부에서만 crop 호출
2055
+ keyword ||= @keyword
2056
+ puts "키워드: #{keyword}"
2057
+
2058
+ client = HTTPClient.new
2059
+ client.default_header = {
2060
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2061
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2062
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2063
+ 'Accept-Language' => 'en-US,en;q=0.9',
2064
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2065
+ 'X-Requested-With' => 'XMLHttpRequest'
2066
+ }
2067
+
2068
+ retry_count = 0
2069
+ max_retries = 10
2070
+ results = []
2071
+
2072
+ begin
2073
+ page = rand(1..15)
2074
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2075
+ puts "Request URL: #{url}"
2076
+ res = client.get(url)
2077
+
2078
+ unless res.status == 200
2079
+ puts "HTTP Error: #{res.status}"
2080
+ raise "HTTP Error"
2081
+ end
2078
2082
 
2079
- selected_url = mm.sample
2080
- Down.download(selected_url, destination: "./image/memory.png")
2081
- puts "이미지 다운로드 완료: #{selected_url}"
2083
+ json = JSON.parse(res.body)
2084
+ results = json['results']
2085
+ mm = []
2082
2086
 
2083
- rescue => e
2084
- retry_count += 1
2085
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2086
- sleep(3)
2087
- if retry_count < max_retries
2088
- retry
2089
- else
2090
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2091
-
2092
- if results && !results.empty?
2093
- random_photo = results.sample
2094
- fallback_url = random_photo.dig('urls', 'full')
2095
- if fallback_url
2096
- Down.download(fallback_url, destination: "./image/memory.png")
2097
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2098
- else
2099
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2100
- color_image
2101
- end
2087
+ results.each do |photo|
2088
+ full_url = photo.dig('urls', 'full').to_s
2089
+ regular_url = photo.dig('urls', 'regular').to_s
2090
+
2091
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
2092
+ regular_url.include?("1080")
2093
+ mm << full_url
2094
+ end
2095
+ end
2096
+
2097
+ if mm.empty?
2098
+ raise "No matching image"
2099
+ end
2100
+
2101
+ selected_url = mm.sample
2102
+ destination_path = "./image/memory.png"
2103
+ Down.download(selected_url, destination: destination_path)
2104
+ puts "이미지 다운로드 완료: #{selected_url}"
2105
+
2106
+ # 오직 auto_image에서만 자르기 호출
2107
+ crop_image_height_under_width(destination_path)
2108
+
2109
+ rescue => e
2110
+ retry_count += 1
2111
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2112
+ sleep(3)
2113
+ if retry_count < max_retries
2114
+ retry
2115
+ else
2116
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2117
+
2118
+ if results && !results.empty?
2119
+ random_photo = results.sample
2120
+ fallback_url = random_photo.dig('urls', 'full')
2121
+ if fallback_url
2122
+ Down.download(fallback_url, destination: "./image/memory.png")
2123
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2124
+ crop_image_height_under_width("./image/memory.png")
2102
2125
  else
2103
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2104
- color_image
2105
- end
2126
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2127
+ color_image
2106
2128
  end
2129
+ else
2130
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2131
+ color_image
2132
+ end
2107
2133
  end
2108
2134
  end
2135
+ end
2136
+
2109
2137
 
2110
2138
  def color_image
2111
2139
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
@@ -2199,57 +2227,104 @@ class Wordpress
2199
2227
  end
2200
2228
 
2201
2229
 
2202
- def image_text(text1, text2)
2230
+ def image_text(text1, text2)
2231
+ begin
2232
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
2233
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2234
+ font2 = './fonts/' + font_files.sample
2235
+
2236
+ # 랜덤 글자색 선택
2237
+ color2 = color.sample
2238
+
2239
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
2240
+ def hex_to_rgb(hex)
2241
+ hex = hex.delete('#')
2242
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
2243
+ end
2244
+
2245
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
2246
+ def color_distance(c1, c2)
2247
+ Math.sqrt(
2248
+ (c1[0] - c2[0])**2 +
2249
+ (c1[1] - c2[1])**2 +
2250
+ (c1[2] - c2[2])**2
2251
+ )
2252
+ end
2253
+
2254
+ # 대비가 충분히 되는 테두리 색상 선택
2255
+ max_attempts = 10
2256
+ stroke_color = nil
2257
+ base_rgb = hex_to_rgb(color2)
2258
+
2259
+ max_attempts.times do
2260
+ candidate = color.sample
2261
+ candidate_rgb = hex_to_rgb(candidate)
2262
+ dist = color_distance(base_rgb, candidate_rgb)
2263
+
2264
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
2265
+ if dist > 100
2266
+ stroke_color = candidate
2267
+ break
2268
+ end
2269
+ end
2270
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2271
+
2272
+ img = Magick::Image.read('./image/memory.png').first
2273
+ draw = Magick::Draw.new
2274
+
2275
+ raw_message = "#{text1}\n#{text2}".strip
2276
+ max_width = img.columns * 0.85
2277
+ max_height = img.rows * 0.6
2278
+
2203
2279
  begin
2204
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2205
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2206
- font2 = './fonts/' + font_files.sample
2207
- color2 = color.sample
2208
-
2209
- img = Magick::Image.read('./image/memory.png').first
2210
- draw = Magick::Draw.new
2211
-
2212
- raw_message = "#{text1}\n#{text2}".strip
2213
- max_width = img.columns * 0.85
2214
- max_height = img.rows * 0.6
2215
-
2216
- begin
2217
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2218
- rescue
2219
- size = 30
2220
- end
2221
-
2222
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2223
-
2224
- if @data['이미지설정']['글자그림자'].checked?
2225
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2226
- draw.gravity = Magick::CenterGravity
2227
- draw.pointsize = adjusted_size
2228
- draw.fill = '#000000'
2229
- draw.font = font2
2230
- end
2231
- end
2232
-
2233
- draw2 = Magick::Draw.new
2234
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2235
- draw2.gravity = Magick::CenterGravity
2236
- draw2.pointsize = adjusted_size
2237
- draw2.fill = color2
2238
- draw2.font = font2
2239
- if @data['이미지설정']['글자테두리'].checked?
2240
- draw2.stroke_width = 2
2241
- draw2.stroke = '#000000'
2242
- end
2243
- end
2244
-
2245
- img.write('./image/memory.png')
2280
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2246
2281
  rescue
2247
- puts '이미지 폰트 불러오기 오류 재시도...'
2248
- sleep(3)
2249
- retry
2282
+ size = 30
2283
+ end
2284
+
2285
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2286
+
2287
+ if @data['이미지설정']['글자그림자'].checked?
2288
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2289
+ draw.gravity = Magick::CenterGravity
2290
+ draw.pointsize = adjusted_size
2291
+ draw.fill = '#000000'
2292
+ draw.font = font2
2293
+ end
2294
+ end
2295
+
2296
+ if @data['이미지설정']['글자테두리'].checked?
2297
+ draw_stroke = Magick::Draw.new
2298
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2299
+ draw_stroke.gravity = Magick::CenterGravity
2300
+ draw_stroke.pointsize = adjusted_size
2301
+ draw_stroke.fill = 'none'
2302
+ draw_stroke.stroke = stroke_color
2303
+ draw_stroke.stroke_width = rand(5..10)
2304
+ draw_stroke.font = font2
2305
+ end
2250
2306
  end
2307
+
2308
+ draw2 = Magick::Draw.new
2309
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2310
+ draw2.gravity = Magick::CenterGravity
2311
+ draw2.pointsize = adjusted_size
2312
+ draw2.fill = color2
2313
+ draw2.stroke = 'none'
2314
+ draw2.font = font2
2315
+ end
2316
+
2317
+ img.write('./image/memory.png')
2318
+
2319
+ rescue => e
2320
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2321
+ sleep(3)
2322
+ retry
2323
+ end
2251
2324
  end
2252
2325
 
2326
+
2327
+
2253
2328
  def border()
2254
2329
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
2255
2330
  img = Magick::Image.read('./image/memory.png').first
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cafe_basics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.51
4
+ version: 0.1.52
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-06-25 00:00:00.000000000 Z
10
+ date: 2025-06-26 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: File to Clipboard gem
13
13
  email: mymin26@naver.com