nblog_zon 111.120.001 → 111.120.002

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/nblog_zon.rb +185 -110
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e878087c2dca81eb560830ac36bef62b0555a09031fb7ea6b8230bee47c0007
4
- data.tar.gz: 9acc1171220502c7395f5674eff0cb07d8df5c4ed1e16168b2d0cc59042e2163
3
+ metadata.gz: 595965e5f3c7b1d69d7c74b60132fdf593929cdae756140076d27e752b293262
4
+ data.tar.gz: 120f11c6c018d9ce3f5c4fe0f6200cc26687343102895b9fea21d9d6b5051c64
5
5
  SHA512:
6
- metadata.gz: 9132d31e3a36202c849b2df2ba64dddd681a41863fde72ad3093cafa4c754764cf33142e02bb5814d7fc356cb321820a0ad878dc197c6c1e0be449a14c126222
7
- data.tar.gz: 9211eca1af240c069a09f4548d1034d20ced569a3268deced7df4ae407b030357665f89959620add1c18243eada3c94533ba9cd50d37bdd794de0ab4bcf79567
6
+ metadata.gz: 98e94f6a657edf2483cb147d0685bf1f22e4778e4cd9cd25c78847e71e452dadc41b3ac39d3fffecd34a905808a5bf7bc8a6e74dafd21b2495588d0cf32d20a0
7
+ data.tar.gz: fd9770bbc34d96c45c3cadd0a452ef31317cdad42ba6dc2466ec47783fc79ce1cfcf4de0f6daefb0acd9af9a2020dc1ff14ffcda7caa5e0dfdb3bc5c787ceb40
data/lib/nblog_zon.rb CHANGED
@@ -2240,83 +2240,111 @@ class Wordpress
2240
2240
  return @data2
2241
2241
  end
2242
2242
 
2243
- def auto_image(keyword = nil)
2244
- keyword ||= @keyword
2245
- puts "키워드: #{keyword}"
2246
-
2247
- client = HTTPClient.new
2248
- client.default_header = {
2249
- 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2250
- '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2251
- 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2252
- 'Accept-Language' => 'en-US,en;q=0.9',
2253
- 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2254
- 'X-Requested-With' => 'XMLHttpRequest'
2255
- }
2243
+ def crop_image_height_under_width(path, min_crop_ratio = 0.625)
2244
+ img = Magick::Image.read(path).first
2245
+ width = img.columns
2246
+ height = img.rows
2256
2247
 
2257
- retry_count = 0
2258
- max_retries = 10
2259
- results = []
2260
2248
 
2261
- begin
2262
- page = rand(1..15)
2263
- url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2264
- puts "Request URL: #{url}"
2265
- res = client.get(url)
2266
-
2267
- unless res.status == 200
2268
- puts "HTTP Error: #{res.status}"
2269
- raise "HTTP Error"
2270
- end
2271
2249
 
2272
- json = JSON.parse(res.body)
2273
- results = json['results']
2274
- mm = []
2250
+ if height > width
2251
+ min_height = (width * min_crop_ratio).to_i
2252
+ new_height = rand(min_height..width)
2253
+ crop_top = ((height - new_height) / 2.0).round
2275
2254
 
2276
- results.each do |photo|
2277
- full_url = photo.dig('urls', 'full').to_s
2278
- regular_url = photo.dig('urls', 'regular').to_s
2255
+ cropped = img.crop(0, crop_top, width, new_height, true)
2256
+ cropped.write(path)
2279
2257
 
2280
- if full_url.start_with?("https://images.unsplash.com/photo-") &&
2281
- regular_url.include?("1080")
2282
- mm << full_url
2283
- end
2284
- end
2258
+
2259
+ else
2260
+
2261
+ end
2262
+ end
2285
2263
 
2286
- if mm.empty?
2287
- raise "No matching image"
2288
- end
2264
+ def auto_image(keyword = nil)
2265
+ # auto_image 내부에서만 crop 호출
2266
+ keyword ||= @keyword
2267
+ puts "키워드: #{keyword}"
2268
+
2269
+ client = HTTPClient.new
2270
+ client.default_header = {
2271
+ 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '\
2272
+ '(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
2273
+ 'Accept' => 'application/json, text/javascript, */*; q=0.01',
2274
+ 'Accept-Language' => 'en-US,en;q=0.9',
2275
+ 'Referer' => "https://unsplash.com/s/photos/#{URI.encode_www_form_component(keyword)}",
2276
+ 'X-Requested-With' => 'XMLHttpRequest'
2277
+ }
2278
+
2279
+ retry_count = 0
2280
+ max_retries = 10
2281
+ results = []
2282
+
2283
+ begin
2284
+ page = rand(1..15)
2285
+ url = "https://unsplash.com/napi/search/photos?query=#{URI.encode_www_form_component(keyword)}&page=#{page}&per_page=20"
2286
+ puts "Request URL: #{url}"
2287
+ res = client.get(url)
2288
+
2289
+ unless res.status == 200
2290
+ puts "HTTP Error: #{res.status}"
2291
+ raise "HTTP Error"
2292
+ end
2289
2293
 
2290
- selected_url = mm.sample
2291
- Down.download(selected_url, destination: "./image/memory.png")
2292
- puts "이미지 다운로드 완료: #{selected_url}"
2294
+ json = JSON.parse(res.body)
2295
+ results = json['results']
2296
+ mm = []
2293
2297
 
2294
- rescue => e
2295
- retry_count += 1
2296
- puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2297
- sleep(3)
2298
- if retry_count < max_retries
2299
- retry
2300
- else
2301
- puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2302
-
2303
- if results && !results.empty?
2304
- random_photo = results.sample
2305
- fallback_url = random_photo.dig('urls', 'full')
2306
- if fallback_url
2307
- Down.download(fallback_url, destination: "./image/memory.png")
2308
- puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2309
- else
2310
- puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2311
- color_image
2312
- end
2298
+ results.each do |photo|
2299
+ full_url = photo.dig('urls', 'full').to_s
2300
+ regular_url = photo.dig('urls', 'regular').to_s
2301
+
2302
+ if full_url.start_with?("https://images.unsplash.com/photo-") &&
2303
+ regular_url.include?("1080")
2304
+ mm << full_url
2305
+ end
2306
+ end
2307
+
2308
+ if mm.empty?
2309
+ raise "No matching image"
2310
+ end
2311
+
2312
+ selected_url = mm.sample
2313
+ destination_path = "./image/memory.png"
2314
+ Down.download(selected_url, destination: destination_path)
2315
+ puts "이미지 다운로드 완료: #{selected_url}"
2316
+
2317
+ # 오직 auto_image에서만 자르기 호출
2318
+ crop_image_height_under_width(destination_path)
2319
+
2320
+ rescue => e
2321
+ retry_count += 1
2322
+ puts "auto_image 에러: #{e.message} (재시도 #{retry_count}/#{max_retries})"
2323
+ sleep(3)
2324
+ if retry_count < max_retries
2325
+ retry
2326
+ else
2327
+ puts "최대 재시도 초과. 조건 무시하고 랜덤 이미지 다운로드 시도..."
2328
+
2329
+ if results && !results.empty?
2330
+ random_photo = results.sample
2331
+ fallback_url = random_photo.dig('urls', 'full')
2332
+ if fallback_url
2333
+ Down.download(fallback_url, destination: "./image/memory.png")
2334
+ puts "랜덤 이미지 다운로드 완료: #{fallback_url}"
2335
+ crop_image_height_under_width("./image/memory.png")
2313
2336
  else
2314
- puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2315
- color_image
2316
- end
2337
+ puts "랜덤 이미지 URL을 찾을 수 없습니다. 단색 배경 이미지 생성합니다."
2338
+ color_image
2317
2339
  end
2340
+ else
2341
+ puts "이미지 결과가 없어 다운로드할 수 없습니다. 단색 배경 이미지 생성합니다."
2342
+ color_image
2343
+ end
2318
2344
  end
2319
2345
  end
2346
+ end
2347
+
2320
2348
 
2321
2349
  def color_image
2322
2350
  color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
@@ -2411,56 +2439,103 @@ class Wordpress
2411
2439
 
2412
2440
 
2413
2441
  def image_text(text1, text2)
2442
+ begin
2443
+ color = File.open('./color.ini', 'r', encoding: 'utf-8').read.split("\n").map(&:strip).reject(&:empty?)
2444
+ font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2445
+ font2 = './fonts/' + font_files.sample
2446
+
2447
+ # 랜덤 글자색 선택
2448
+ color2 = color.sample
2449
+
2450
+ # 헬퍼 함수: 색상 문자열 '#RRGGBB' -> [R,G,B] 배열로 변환
2451
+ def hex_to_rgb(hex)
2452
+ hex = hex.delete('#')
2453
+ [hex[0..1], hex[2..3], hex[4..5]].map { |c| c.to_i(16) }
2454
+ end
2455
+
2456
+ # 헬퍼 함수: 두 RGB 색상의 차이 계산 (간단한 유클리드 거리)
2457
+ def color_distance(c1, c2)
2458
+ Math.sqrt(
2459
+ (c1[0] - c2[0])**2 +
2460
+ (c1[1] - c2[1])**2 +
2461
+ (c1[2] - c2[2])**2
2462
+ )
2463
+ end
2464
+
2465
+ # 대비가 충분히 되는 테두리 색상 선택
2466
+ max_attempts = 10
2467
+ stroke_color = nil
2468
+ base_rgb = hex_to_rgb(color2)
2469
+
2470
+ max_attempts.times do
2471
+ candidate = color.sample
2472
+ candidate_rgb = hex_to_rgb(candidate)
2473
+ dist = color_distance(base_rgb, candidate_rgb)
2474
+
2475
+ # 거리(차이) 임계값 100 (0~441 범위) — 필요시 조절 가능
2476
+ if dist > 100
2477
+ stroke_color = candidate
2478
+ break
2479
+ end
2480
+ end
2481
+ stroke_color ||= '#000000' # 만약 충분히 다른 색 없으면 검정색 기본값
2482
+
2483
+ img = Magick::Image.read('./image/memory.png').first
2484
+ draw = Magick::Draw.new
2485
+
2486
+ raw_message = "#{text1}\n#{text2}".strip
2487
+ max_width = img.columns * 0.85
2488
+ max_height = img.rows * 0.6
2489
+
2414
2490
  begin
2415
- color = File.open('./color.ini', 'r', :encoding => 'utf-8').read().split("\n")
2416
- font_files = Dir.entries('./fonts').select { |f| f.downcase.end_with?('.ttf') }
2417
- font2 = './fonts/' + font_files.sample
2418
- color2 = color.sample
2419
-
2420
- img = Magick::Image.read('./image/memory.png').first
2421
- draw = Magick::Draw.new
2422
-
2423
- raw_message = "#{text1}\n#{text2}".strip
2424
- max_width = img.columns * 0.85
2425
- max_height = img.rows * 0.6
2426
-
2427
- begin
2428
- size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2429
- rescue
2430
- size = 30
2431
- end
2432
-
2433
- wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2434
-
2435
- if @data['이미지설정']['글자그림자'].checked?
2436
- img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2437
- draw.gravity = Magick::CenterGravity
2438
- draw.pointsize = adjusted_size
2439
- draw.fill = '#000000'
2440
- draw.font = font2
2441
- end
2442
- end
2443
-
2444
- draw2 = Magick::Draw.new
2445
- img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2446
- draw2.gravity = Magick::CenterGravity
2447
- draw2.pointsize = adjusted_size
2448
- draw2.fill = color2
2449
- draw2.font = font2
2450
- if @data['이미지설정']['글자테두리'].checked?
2451
- draw2.stroke_width = 2
2452
- draw2.stroke = '#000000'
2453
- end
2454
- end
2455
-
2456
- img.write('./image/memory.png')
2491
+ size = rand(@data['이미지설정']['이미지글자1크기1'].text.to_i..@data['이미지설정']['이미지글자1크기2'].text.to_i)
2457
2492
  rescue
2458
- puts '이미지 폰트 불러오기 오류 재시도...'
2459
- sleep(3)
2460
- retry
2493
+ size = 30
2494
+ end
2495
+
2496
+ wrapped_message, adjusted_size = wrap_text_to_fit(draw, raw_message, max_width, max_height, font2, size)
2497
+
2498
+ if @data['이미지설정']['글자그림자'].checked?
2499
+ img.annotate(draw, 0, 0, 2, 2, wrapped_message) do
2500
+ draw.gravity = Magick::CenterGravity
2501
+ draw.pointsize = adjusted_size
2502
+ draw.fill = '#000000'
2503
+ draw.font = font2
2504
+ end
2505
+ end
2506
+
2507
+ if @data['이미지설정']['글자테두리'].checked?
2508
+ draw_stroke = Magick::Draw.new
2509
+ img.annotate(draw_stroke, 0, 0, 0, 0, wrapped_message) do
2510
+ draw_stroke.gravity = Magick::CenterGravity
2511
+ draw_stroke.pointsize = adjusted_size
2512
+ draw_stroke.fill = 'none'
2513
+ draw_stroke.stroke = stroke_color
2514
+ draw_stroke.stroke_width = rand(5..10)
2515
+ draw_stroke.font = font2
2516
+ end
2461
2517
  end
2518
+
2519
+ draw2 = Magick::Draw.new
2520
+ img.annotate(draw2, 0, 0, 0, 0, wrapped_message) do
2521
+ draw2.gravity = Magick::CenterGravity
2522
+ draw2.pointsize = adjusted_size
2523
+ draw2.fill = color2
2524
+ draw2.stroke = 'none'
2525
+ draw2.font = font2
2526
+ end
2527
+
2528
+ img.write('./image/memory.png')
2529
+
2530
+ rescue => e
2531
+ puts "이미지 폰트 불러오기 오류 재시도... (#{e.message})"
2532
+ sleep(3)
2533
+ retry
2534
+ end
2462
2535
  end
2463
2536
 
2537
+
2538
+
2464
2539
  def border()
2465
2540
  color = File.open('./color.ini', 'r',:encoding => 'utf-8').read().split("\n")
2466
2541
  img = Magick::Image.read('./image/memory.png').first
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nblog_zon
3
3
  version: !ruby/object:Gem::Version
4
- version: 111.120.001
4
+ version: 111.120.002
5
5
  platform: ruby
6
6
  authors:
7
7
  - zon